【问题标题】:Passing custom props to each styled component through Provider通过 Provider 将自定义 props 传递给每个样式化的组件
【发布时间】:2019-11-26 10:29:47
【问题描述】:

我想通过 Provider 将自定义 prop(确切地说:主题名称作为字符串)传递给每个传递的样式组件,因此它在整个 css 定义中都可用。 ThemeProvider 几乎做到了,但它需要对象,而不是字符串。我不想通过主题设置传递整个对象,只传递我的主题名称。

我不想使用特殊的主题道具或类似的道具,因为这样我每次创建新的样式组件时都必须手动进行。提供者似乎是最好的选择,如果它只与字符串合作。

是否有可能通过 Provider 将字符串传递给内置样式组件的 Consumer?

编辑:

[部分解决方案]

当我意识到 styled-components 导出它们的内部上下文时,我找到了我正在寻找的东西。就是这样。访问纯反应上下文为您提供原始提供者,没有任何“仅对象”限制(“仅对象”是样式化组件自定义提供者限制)。 现在,我可以将我想要的以及我想要的推送到每个样式化的组件。

import styled, { ThemeContext } from 'styled-components';

const StyledComponent = styled.div`
  color: ${props => props.theme == 'dark' ? 'white' : 'black'};
`;

const Component = props => {

  const theme = 'dark';

  return (
    <ThemeContext.Provider value={theme}>
      <NextLevelComponent>
        <StyledComponent />
      </NextLevelComponent>
    </ThemeContext.Provider>
  );
};

【问题讨论】:

    标签: reactjs styled-components


    【解决方案1】:

    希望我有这个正确的,从我已经能够收集到的。我还没有尝试过,但它似乎对你有用。这是 reactjs.org 文档中有关上下文的 lifted directly。它将主题的字符串名称向下传递。

    const ThemeContext = React.createContext('green');
    
    class App extends React.Component {
      render() {
        return (
          <ThemeContext.Provider value="blue">
            <SomeComponent />
          </ThemeContext.Provider>
        );
      }
    }
    
    function SomeComponent(props) {
      return (
        <div> 
          <OtherComponent />
        </div>
      );
    }
    
    class OtherComponent extends React.Component {
      static contextType = ThemeContext;
      render() {
        return <ThirdComponent theme={this.context} />
      }
    }
    

    【讨论】:

    • 你写的是Context的大致思路,大概没问题。但是在 styled-components 中已经有一个 Consumer 有自己的 context,并且它被注入到每个新的 styled 组件中。因此我需要以某种方式编辑 ThemeProvider 或者....获取现有上下文并创建我自己的提供者....嗯
    【解决方案2】:

    我希望这可以帮助您从 styled-components 中理解 ThemeContext 背后的想法。我将字符串“blue”传递给 ThemeContext 只是为了表明它不应该是对象,您可以只使用字符串。

    import React, { useContext } from "react";
    import ReactDOM from "react-dom";
    import styled, { ThemeContext } from "styled-components";
    
    // Define styled button
    const Button = styled.button`
      font-size: 1em;
      margin: 1em;
      padding: 0.25em 1em;
      border-radius: 3px;
      color: ${props => props.theme};
      border: 2px solid ${props => props.theme};
    `;
    
    // Define the name of the theme / color (string)
    const themeName = "blue";
    
    const ThemedButton = () => {
      // Get the name from context
      const themeName = useContext(ThemeContext);
      return <Button theme={themeName}>Themed color: {themeName}</Button>;
    };
    
    function App() {
      return (
        <div className="App">
          <ThemeContext.Provider value={themeName}>
            <ThemedButton />
          </ThemeContext.Provider>
        </div>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    演示:https://codesandbox.io/s/styled-components-example-with-themecontext-cso55

    【讨论】:

    • 好吧,你的代码也是准确的,但它仍然不是我想要的。您使用 ThemedButton 作为一种中间件来应用上下文值。这意味着我必须包装 >each
    猜你喜欢
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多