reactjs - 为什么 styled-components 中的反引号可以访问 props.theme?

标签 reactjs styled-components

我对反引号在样式化组件中的工作方式有疑问。

假设我使用他们的 ThemeProvider 定义并传递了一个主题:

const theme = {
  primary: '#df0000',
}

ReactDOM.render(
  <ThemeProvider theme={theme}>
    <App />
  </ThemeProvider>
  ,
  document.getElementById('root')
)

我可以像这样在 App.js 中定义一个访问 props.theme.primary 的“样式化 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

这很好,除了 props.theme 只能由 Div 访问,因为它位于反引号内的 ${} 中。 console.log(props.theme)undefined。但是,如果我使用 export default withTheme(App),我会看到 console.log 打印了主题。

样式组件中的反引号如何允许访问 props.theme

最佳答案

所有带样式的组件都可以从上下文内部访问主题(如果存在)。

无论您在哪里定义组件,它在呈现时仍然能够访问上下文。

这是 the current implementation 的链接您可以在其中看到它正在访问上下文。

  // Snippet from StyledComponent.js

  const theme = determineTheme(props, useContext(ThemeContext), defaultProps);

但是您的问题具体是关于反引号如何工作的,所以这里是其余的答案:

样式化组件使用模板文字,特别是标记模板功能。

这是摘录 from MDN:

Tagged templates

A more advanced form of template literals are tagged templates.

Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions.

The tag function can then perform whatever operations on these arguments you wish, and return the manipulated string. (Alternatively, it can return something completely different, as described in one of the following examples.)

所以在你的例子中:

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
)

一旦标记的模板被拆分成字符串和函数。它被包装到样式组件中。在渲染时,所有函数都使用样式化组件的属性(以及上下文中的主题)调用。

每个用 props 调用的函数都会返回一个字符串。然后我们可以将字符串数组和函数的返回值拼接在一起,最后得到最终的样式。

 ['background-color: ', ';'],
  props => props.theme.primary // returns a string e.g. "green"

现在我们有了所有的字符串,它们可以作为样式重新缝合在一起:

  'background-color: ' + 'green' + ';'

在引擎盖下进行了优化,但这是样式化组件反引号工作原理的基础。

其中一位创作者拥有 great blog post以及有关带样式组件标记模板的更多信息。

关于reactjs - 为什么 styled-components 中的反引号可以访问 props.theme?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57237912/

相关文章:

reactjs - redux thunk 中的 getState() 是否会改变实际状态

javascript - 函数是否作为 props 在此代码中传递?

javascript - Styled-component 在 Internet Explorer 11 上不工作的解决方法

javascript - react 状态内部的 Prop 解构

reactjs - Next.js-express 动态路由导致页面重新加载

reactjs - CommonJS 导入与 ES6 导入

css - 为什么 flex-value 没有在 styled-component 中更新?

javascript - 对样式组件概念的误解

react-native - React Native - 带有样式组件的样式按钮

javascript - 如何为 React UI 库添加全局样式选项?