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

Using Emotion CSS-in-JS with theming in React

首先,我是 React 的新手,所以我仍在学习。

我正在关注 Introduction Article (Medium.com) on setting up using Themes with Emotion。但是我坚持尝试在将在 compose

中使用的 const 中使用主题颜色

例如,我有:

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};
`);

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

我不太确定我做错了什么。

一点背景知识:

ES2015的

Tagged template literals是模板字面量,可以通过'tagging'一个函数来解析(比如styled.button)。该函数接收模板文字和所有 ${} 占位符和 return 生成的字符串。 ${} 可以包含任何被视为 javascript 表达式的内容,例如单个值、函数等

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

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

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]};
`);

在 'primary' 的情况下,上面的计算结果为:

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

如您所见,这个级别太深了。主题将作为 props 的一部分传入,但需要调用第二个更深的函数才能调用 css 函数。在第二个代码块中,'primary' 的计算结果为:

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

这会给出正确的结果,因为 styled.button 将传入道具,css 直接在被调用函数中使用它们。

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