React 中的样式有各种形状和大小。开箱即用,您可以通过className
属性分配类或通过将对象传递给属性来分配 CSSstyle
属性。虽然在大多数情况下足够了,但它们并非没有缺点。使classNames
动态化需要定义额外的类,并且styles
,虽然允许动态属性,但仍然需要样板代码,并且不允许您深入研究像:hover
. 这就是 Fela 可以帮助您的地方!
Fela是一个与框架无关的库,用于处理 JavaScript 中的状态驱动样式。它具有很高的性能,并且在使用方式方面为您提供了一定的灵活性。虽然您可以单独使用 Fela,但react-fela可用于为您的 React.js 应用程序提供 React 绑定。
入门
首先,我们需要添加react-fela
到我们的项目中:
通过 npm
$ npm install --save react-fela
或通过纱线
$ yarn add react-fela
对于本文,我们将直接使用fela
库中的一些方法。不过别担心,react-fela
包括这个依赖项,所以我们应该很高兴。
渲染器
正如承诺的那样,fela
我们需要使用库的一部分,即createRenderer
. 该createRenderer
方法用于创建一个渲染器,该渲染器将传递一个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。
享受!