如何引用作为功能组件的样式组件?

Gaj*_*jus 1 javascript reactjs styled-components next.js

这是我能想到的最基本的例子:

\n
import React from \'react\';\nimport {\n  css,\n} from \'styled-components\';\n\nconst Foo = (props) => {\n  console.log(props);\n\n  const {\n    children,\n  } = props;\n\n  return <div {...props}>{children}</div>;\n};\n\nexport default () => {\n  return <div\n    css={css`\n      ${Foo} {\n        background: #f00;\n      }\n    `}\n  >\n    <Foo>FOO</Foo>\n  </div>;\n};\n\n
Run Code Online (Sandbox Code Playgroud)\n

在此示例中,我想要Foo为 . 的后代组件设置样式div

\n

我希望生成的标记看起来像这样:

\n
<div class="test__Foo-wusfqk-0 hNfawX">FOO</div>\n\n
Run Code Online (Sandbox Code Playgroud)\n

然而,它只是:

\n
<div>FOO</div>\n\n
Run Code Online (Sandbox Code Playgroud)\n

似乎任何地方都没有应用任何样式。

\n

此外,该组件Foo仅渲染一次,但使用不同的参数调用两次:

\n
{children: {\xe2\x80\xa6}, theme: {\xe2\x80\xa6}}\n  children: {$$typeof: Symbol(react.element), key: null, ref: null, props: {\xe2\x80\xa6}, type: \xc6\x92, \xe2\x80\xa6}\n  theme: {}\n\n{children: "FOO"}\n
Run Code Online (Sandbox Code Playgroud)\n

我应该提到我尝试过:

\n
{children: {\xe2\x80\xa6}, theme: {\xe2\x80\xa6}}\n  children: {$$typeof: Symbol(react.element), key: null, ref: null, props: {\xe2\x80\xa6}, type: \xc6\x92, \xe2\x80\xa6}\n  theme: {}\n\n{children: "FOO"}\n
Run Code Online (Sandbox Code Playgroud)\n

但是,当在中执行此代码时,我收到以下错误:

\n
\n

id 为“sc-dlnjPT”的组件 Styled(Component) 已动态创建。

\n

您可能会看到此警告,因为您在另一个组件内调用了 styled。

\n

要解决此问题,只需在任何渲染方法和函数组件之外创建新的 StyledComponent。

\n

id 为“sc-hKFyIo”的组件 Styled(Component) 已动态创建。

\n

您可能会看到此警告,因为您在另一个组件内调用了 styled。

\n

要解决此问题,只需在任何渲染方法和函数组件之外创建新的 StyledComponent。

\n

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。发生这种情况可能是由于以下原因之一:

\n
    \n
  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. \n
  3. 你可能违反了 Hooks 规则
  4. \n
  5. 您可能在同一个应用程序中拥有多个 React 副本
  6. \n
\n
\n

考虑到主题代码片段,这没有多大意义。

\n

Oma*_*mar 5

主要问题是它<Foo />不是一个样式组件,它是一个功能组件

我认为你需要做

const Foo = styled.div`
    background: #f00;
`
Run Code Online (Sandbox Code Playgroud)

Foo然后你可以改变使用风格css$参考

您的代码不起作用的原因如下

此行为仅在样式组件的上下文中受支持:在以下示例中尝试挂载 B 将失败,因为组件 Foo 是 React.Component 的实例而不是样式组件。

const Foo = () => <div> </div>

const B = styled.div`
  ${Foo} {
  }
`
Run Code Online (Sandbox Code Playgroud)

然而,将 Foo 包装在 styled() 工厂中使其可以进行插值——只需确保包装的组件沿着 className 传递即可。

const Foo = (props) => {
  console.log(props);

  const {
    children,
  } = props;

  return <div className="Test-Class" {...props}>{children}</div>;
};

const StyledFoo = styled(Foo)``

const Main = styled.div`
  ${StyledFoo} {
    background: #f00;
  }
`
Run Code Online (Sandbox Code Playgroud)

代码沙箱

import { render } from "react-dom";
import React from "react";
import styled from "styled-components";

const Foo = (props) => {
  const { className, children } = props;

  return <div className={className}>{children}</div>;
};

const Bar = styled(Foo)``;

const Main = styled.div`
  ${Bar} {
    background-color: #000;
    color: #fff;
  }
`;
const App = () => {
  return (
    <Main>
      {" "}
      <Bar>Hello </Bar>{" "}
    </Main>
  );
};

render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)

https://codesandbox.io/s/styled-components-forked-5s201?file=/index.js