【问题标题】:Where should styled component styles live in the tree of components?样式化的组件样式应该放在组件树的什么位置?
【发布时间】:2018-12-05 18:34:05
【问题描述】:

在样式化的组件环境中,假设我有:

<Header>
  <List ...>
    <ListItem ... />
    <ListItem ... />
    <ListItem ... />
  </List>
</Header>

我想为 ListItem 设置一些样式,这些样式仅在此组件在 Header 中使用时才应用。

我是否应该将一个 prop 传递给 List,然后这个组件应该将它传递给 ListItem,以便我可以在 ListItem 中包含一组样式?

或者

我是否应该在 Header 中设置 ListItem 的样式,因为它们是只会使用一次的样式,而且我不想让 ListItem 弄脏我的整个应用程序中可能发生的所有可能性。另外,我无权访问呈现的 ListItem 组件,因为它们是由 List 呈现的。

【问题讨论】:

标签: css styled-components


【解决方案1】:

似乎你可以不在这里传递 prop :它可以单独使用 CSS 特异性来处理。例如,您可以为列表项添加相应的类名,这将告诉 Header 样式的组件选择器为其应用样式,如下所示:

const HeaderWithClassNameSpecificity = styled.div`
  .inside-header { // apply this to Header children with className="inside-header"
    background: salmon;
  }
`;

您的列表项将如下所示:

 <ListItem className="inside-header" />

另一种方法是根据标签名称的特殊性设置 Header 子项的样式,您的 Header 将是

const HeaderWithTagNameSpecificity = styled.div`
  ul li {  // apply this to Header children which are <li> items inside <ul>
    background: salmon;
  }
`;

所以您不需要将 className 添加到 ListItem,只要它是一个“li”项,它是“ul”的子项。

这两种方法之间的选择将取决于您的整体应用架构,但请记住,基于类的特异性在浏览器性能方面更合适(当您有许多相同的标签和相当复杂的标签选择器时,应该考虑CSS)。

在此处检查概念证明:https://codesandbox.io/s/wy35njlmyl

【讨论】:

    【解决方案2】:

    styled-componentsreferring to other components 提供了一种内置方式:

    const Container = styled.div`
      ${Header} {
        background-color: yellow;
      }
    `;
    

    例子:

    const { render } = ReactDOM;
    const styled = styled.default;
    
    const Header = styled.h1`
      color: red;
    `;
    
    const Container = styled.div`
      ${Header} {
        background-color: yellow;
      }
    `;
    
    function App() {
      return (
        <main>
          <Header>Header</Header>
          <Container>
            <Header>Header inside Container</Header>
          </Container>
        </main>
      );
    }
    
    render(<App />, document.getElementById("root"));
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/styled-components/3.4.10/styled-components.js"></script>
    <div id="root"></div>

    【讨论】:

      最近更新 更多