imy*_*mmy 3 reactjs styled-components
我有一个关于反引号如何在样式组件中工作的问题。
假设我使用它们定义并传递了一个主题ThemeProvider:
const theme = {
primary: '#df0000',
}
ReactDOM.render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
,
document.getElementById('root')
)
Run Code Online (Sandbox Code Playgroud)
我可以定义一个props.theme.primary在 App.js中访问的“样式 Div”,如下所示:
const App = props => {
const Div = styled.div`
background-color: ${props => props.theme.primary};
`
return (
<>
{console.log(props)}
<h1>Welcome to React Parcel Micro App!</h1>
<p>Hard to get more minimal than this React app.</p>
<Div>lol</Div>
</>
)
}
export default App
Run Code Online (Sandbox Code Playgroud)
太好了,除了props.theme只能由 Div 访问,因为它${}在反引号内。console.log(props.theme)说undefined。但是,如果我使用,export default withTheme(App)我会看到 console.log 打印主题。
样式组件中的反引号如何允许访问props.theme?
如果存在,所有样式组件都可以从上下文内部访问主题。
无论您在哪里定义组件,它仍然可以在呈现时访问上下文。
这是当前实现的链接,您可以在其中看到它访问上下文。
// Snippet from StyledComponent.js
const theme = determineTheme(props, useContext(ThemeContext), defaultProps);
Run Code Online (Sandbox Code Playgroud)
但是您的问题特别是关于反引号的工作原理,所以这里是其余的答案:
样式组件使用template literals,特别是tagged templates功能。
标记模板
更高级的模板文字形式是标记模板。
标签允许您使用函数解析模板文字。标签函数的第一个参数包含一个字符串值数组。其余参数与表达式相关。
然后,标记函数可以对这些参数执行任何您希望的操作,并返回操作过的字符串。(或者,它可以返回完全不同的内容,如以下示例之一中所述。)
所以在你的例子中:
const Div = styled.div`
background-color: ${props => props.theme.primary};
`
// is conceptually like calling the styled.div function with the following arguments:
(
['background-color: ', ';'], // array of strings,
props => props.theme.primary // each expression is passed in as a new param
)
Run Code Online (Sandbox Code Playgroud)
一旦标记模板被拆分为字符串和函数。它被包裹在样式组件中。在渲染时,所有函数都使用样式组件的道具(以及上下文中的主题)调用。
使用 props 调用的每个函数都返回一个字符串。然后我们可以将字符串数组和函数的返回值拼接在一起,我们最终得到了最终的样式。
['background-color: ', ';'],
props => props.theme.primary // returns a string e.g. "green"
Run Code Online (Sandbox Code Playgroud)
现在我们有了所有可以作为样式缝合在一起的字符串:
'background-color: ' + 'green' + ';'
Run Code Online (Sandbox Code Playgroud)
在幕后进行了优化,但这是样式组件反引号如何工作的基础知识。
其中一位创建者有一篇很棒的博客文章,其中包含有关样式组件标记模板的更多信息。
| 归档时间: |
|
| 查看次数: |
817 次 |
| 最近记录: |