在 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]};
`);
(这是一个人为的例子。实际上,我的 primary
和 secondary
会有更多 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
直接在被调用函数中使用它们。
希望这是有道理的。这是我的第一个堆栈溢出答案尝试,所以如果可以的话,我很乐意改进它。
首先,我是 React 的新手,所以我仍在学习。
我正在关注 Introduction Article (Medium.com) on setting up using Themes with Emotion。但是我坚持尝试在将在 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]};
`);
(这是一个人为的例子。实际上,我的 primary
和 secondary
会有更多 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
直接在被调用函数中使用它们。
希望这是有道理的。这是我的第一个堆栈溢出答案尝试,所以如果可以的话,我很乐意改进它。