2017-08-26 55 views
1

首先,我对React相当陌生,所以我仍然在学习我的方法。在React中使用情绪CSS-in-JS与主题

我在使用ThemesEmotion设置Introduction Article (Medium.com)。但我坚持试图将内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]}; 
`); 

(这是一个人为的例子在现实中,我如果我渲染<Button type="primary">A Button</Button>,则颜色不会被应用。事实上,如果我检查元素,我甚至不会看到color样式。

但是,如果不是我改变Button到:

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

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

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

回答

2

只是一个小背景:

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

对于情感上的styled,如果你传递一个函数到任何占位符中,它会调用该函数,传入你已经使用的元素的道具(在您的示例a button)作为第一个参数。如果使用withTheme调用将styled模板文字包装起来,那么该参数对象将包含您最初在应用的基本组件处提供给<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函数。在第二个代码块中,“主要”将评估为:

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

这将给出正确的结果作为styled.button将通过道具和css直接使用它们所调用的函数内。

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