在React中使用Emotion CSS-in-JS和主题

时间:2017-08-26 12:38:14

标签: reactjs theming styled-components emotion

首先,我对React很新,所以我还在学习。

我在使用Introduction Article (Medium.com) Themes进行Emotion设置后here。但是我一直试图在const中使用主题颜色,这将在compose

中使用

例如,我有:

const types = {
  primary: (props) => css`color: ${props.theme.blue}`,
  secondary: (props) => css`color: ${props.theme.red}`
};

const Button = withTheme(styled.button`
  composes: ${props => types[props.type]};
`);

(这是一个人为的例子。实际上,我的primarysecondary会有更多的CSS。)

如果我渲染<Button type="primary">A Button</Button>,则颜色不会被应用。事实上,如果我检查元素,我甚至不会看到color样式。

但是,如果我将Button更改为:

const Button = withTheme(styled.button`
  composes: ${types.primary};
`);

然后我看到正确的颜色应用。

我不完全确定我在这里做错了什么。

1 个答案:

答案 0 :(得分:3)

只是一点背景:

ES2015的

Tagged template literals是模板文字,可以通过标记&#39;来解析函数。它有一个(例如styled.button)。该函数接收模板文字和所有${}占位符,并返回结果字符串。 ${}可以包含任何被视为javascript表达式的内容,例如单个值,功能等

如果感情为styled,如果将函数传递给任何占位符,它将调用该函数,传入您使用的styled元素的道具(在您的例如,button)作为第一个参数。如果您使用styled调用包装withTheme模板文字,那么props参数对象将包含您最初提供给应用程序<ThemeProvider>的主题道具基础组件。

在您的示例中,它适用于第二个代码块的原因是因为您传递的函数将返回一个值。在第一个代码块中,您传递的函数在被调用时将返回另一个函数。这意味着生成的样式将包含一个函数,而不是一个值。

const types = {
  primary: (props) => css`color: ${props.theme.blue}`,
  secondary: (props) => css`color: ${props.theme.red}`
};

const Button = withTheme(styled.button`
  composes: ${props => types[props.type]};
`);

对于&#39; primary&#39;以上评估为:

const Button = withTheme(styled.button`
  composes: ${props => (props) => css`color: ${props.theme.blue}`};
`);

正如您所看到的那样,这个级别太深了。主题将作为props的一部分传入,但需要调用第二个更深层的函数来调用css函数。在第二个代码块中,&#39; primary&#39;会评价:

const Button = withTheme(styled.button`
  composes: ${(props) => css`color: ${props.theme.blue}`};
`);

这会得到正确的结果,因为styled.button会传递道具,而css会直接在被调用的函数中使用它们。

希望这有一定道理。这是我的第一次堆栈溢出应答尝试,所以如果可以,我很乐意改进它。