从序列化的字符串生成样式化的组件

时间:2019-01-30 01:26:12

标签: styled-components

是否可以从序列化的字符串创建样式化组件?我是否需要将字符串解析为实际函数以支持插值变体?我可能存储的字符串示例:

// this is a serialized string from storage:

background-color: black;

${p => p.white && css`
  background-color: white;
`}

我希望能够做这样的事情:

const MyComp = styled.div`
  ${myComponentStringFromStorage}
`;

<MyComp white /> // works, but displays the black background

这适用于基本的CSS规则,但是它错过了我的函数,因为它们只是作为字符串中的文本而不是实际函数传递。

我猜想我需要编写一个解析器,以将字符串分解为要发送到带样式的组件工厂函数中的真实函数吗?

好奇“样式化组件”是否为此内置了辅助功能,或者是否有其他方法。

1 个答案:

答案 0 :(得分:1)

您可以在存储的字符串上使用eval并与styled.div一起使用,以创建一个组件。

const MyComp = eval("styled.div`" + myComponentStringFromStorage + "`");

请记住eval可能很危险,并且此操作将在运行时完成,因此在不支持模板字符串的环境中将无法使用。

const { css } = styled;

const myComponentStringFromStorage = [
  "background-color: black;\n",
  "\n",
  "${p => p.white && css`\n",
  "  background-color: white;\n",
  "`}"
].join("");

const MyComp = eval("styled.div`" + myComponentStringFromStorage + "`");

class App extends React.Component {
  render() {
    return <MyComp white>Foo</MyComp>;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>

<div id="root"></div>