使用ReactFela设计组件

来自菜鸟教程
跳转至:导航、​搜索

React 中的样式有各种形状和大小。 开箱即用,您可以通过 className 属性分配类或通过将对象传递给 style 属性来分配 CSS 属性。 虽然在大多数情况下足够了,但它们并非没有缺点。 使 classNames 动态需要定义额外的类,而 styles 虽然允许动态属性,但仍然需要样板代码并且不允许您深入挖掘 :hover 等伪类属性. 这就是费拉可以来拯救你的地方!

Fela 是一个与框架无关的库,用于处理 JavaScript 中的状态驱动样式。 它是高性能的,并且在如何使用它方面为您提供了一些灵活性。 虽然您可以单独使用 Fela,但 react-fela 可用于为您的 React.js 应用程序提供 React 绑定。

入门

首先,我们需要将 react-fela 添加到我们的项目中:

通过 npm

$ npm install --save react-fela

或通过纱线

$ yarn add react-fela

在本文中,我们将直接使用 fela 库中的一些方法。 不过不用担心,react-fela 包含了这个依赖,所以我们应该很高兴。

渲染器

正如所承诺的,我们需要使用 fela 库的一部分,即 createRenderercreateRenderer 方法用于创建一个渲染器,该渲染器将传递一个 Provider 组件,该组件将包装使用 Fela 的组件。

以下所有示例都将包含我们需要使魔术发生的样板代码。

使用生成的 CSS 类

最不复杂的 Fela 示例并不理想,但样板代码量最少。

Fela 的工作方式是它采用您的样式,使用原子类生成适当的 CSS,并允许您获取可以传递给任何组件的 classNames 属性的 CSS 类:

import React from "react";
import { render } from "react-dom";

import { createRenderer } from "fela";
import { Provider } from "react-fela";

const renderer = createRenderer();

const rule = ({
  backgroundColor = "#6db65b",
  borderColor = "#efbb35",
  padding
}) => ({
  backgroundColor: backgroundColor,
  border: `10px solid ${borderColor}`,
  color: "#fff",
  fontWeight: "bold",
  padding: `${padding}px`,
  ":hover": {
    cursor: "pointer",
    filter: "drop-shadow(0 10px 19px rgba(0, 0, 0, 0.3))"
  }
});

const container = document.createElement("div");
document.body.appendChild(container);
render(
  <Provider renderer={renderer}>
    <div className={renderer.renderRule(rule, { padding: 100 })}>
      Hover Over Me!
    </div>
  </Provider>,
  container
);

正如您在示例中看到的,renderer 用于根据传入的 CSS 属性的对象生成我们的 CSS 和类名。

rule 只是一个简单的匿名函数,它返回一个包含我们所有属性的对象,包括可能已传入的任何属性。

因为 rule 只是一个带有返回对象的函数,所以您可以根据需要扩展并包含其他逻辑,而不是立即返回预期的对象。

使用组件原语

虽然以前的方法效果很好,但有时创建一个可以在整个项目中轻松重用的新组件也很好。

在这些场景中,我们可以利用 FelaComponent 原始组件来创建一个新组件:

import React from "react";
import { render } from "react-dom";

import { createRenderer } from "fela";
import { FelaComponent, Provider } from "react-fela";

const renderer = createRenderer();

const rule = ({
  backgroundColor = "#6db65b",
  borderColor = "#efbb35",
  padding
}) => ({
  backgroundColor: backgroundColor,
  border: `10px solid ${borderColor}`,
  color: "#fff",
  fontWeight: "bold",
  padding: `${padding}px`,
  ":hover": {
    cursor: "pointer",
    filter: "drop-shadow(0 10px 19px rgba(0, 0, 0, 0.3))"
  }
});

const PaddedContainer = ({
  backgroundColor,
  borderColor,
  padding,
  children
}) => (
  <FelaComponent
    rule={rule}
    backgroundColor={backgroundColor}
    borderColor={borderColor}
    padding={padding}
  >
    {children}
  </FelaComponent>
);

const container = document.createElement("div");
document.body.appendChild(container);
render(
  <Provider renderer={renderer}>
    <PaddedContainer padding={100}>
      Hover Over Me!
    </PaddedContainer>
  </Provider>,
  container
);

利用类似的 rule,我们可以创建一个新的 PaddedContainer 组件,我们可以直接将属性传递给它,而无需通过 renderRule 分配类和分配类。

自己创建组件

使用原语创建新组件并没有错,但与直接创建组件相比,您往往会得到更多样板:

import React from "react";
import { render } from "react-dom";

import { createRenderer } from "fela";
import { createComponent, Provider } from "react-fela";

const renderer = createRenderer();

const rule = ({
  backgroundColor,
  borderColor,
  padding
}) => ({
  backgroundColor: backgroundColor,
  border: `10px solid ${borderColor}`,
  color: "#fff",
  fontWeight: "bold",
  padding: `${padding}px`,
  ":hover": {
    cursor: "pointer",
    filter: "drop-shadow(0 10px 19px rgba(0, 0, 0, 0.3))"
  }
});

const AnotherPaddedContainer = createComponent(rule);

const container = document.createElement("div");
document.body.appendChild(container);
render(
  <Provider renderer={renderer}>
    <AnotherPaddedContainer padding={100}>Hover Over Me!</AnotherPaddedContainer>
  </Provider>,
  container
);

像我们使用原始组件的示例一样更简洁且可重用!

结论

无论您采用哪种方法,利用 react-fela 可以通过消除您必须编写的大量样板来加快在 React 中动态样式组件所需的时间。

要查看上面的代码示例,请转到 CodeSandbox

享受!