3

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

我正在关注关于设置使用Themes with Emotion的介绍文章 (Medium.com)。但我坚持尝试在 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。)

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

但是,如果改为Button

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

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

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

4

1 回答 1

4

只是一点背景:

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

styled从情绪的情况下,如果您将一个函数传递给任何占位符,它将调用该函数,并将styled您使用的元素的道具(在您的示例中button)作为第一个参数传递。如果您使用调用包装styled模板文字,则该参数对象将包含您最初提供给应用程序基础组件的主题道具。withThemeprops<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]};
`);

在“主要”的情况下,上述计算结果为:

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直接在被调用的函数中使用它们。

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

于 2017-08-31T21:28:12.840 回答