【问题标题】:How do I reference a styled-component that is a functional component?如何引用作为功能组件的样式组件?
【发布时间】:2021-01-25 02:11:30
【问题描述】:

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

import React from 'react';
import {
  css,
} from 'styled-components';

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

  const {
    children,
  } = props;

  return <div {...props}>{children}</div>;
};

export default () => {
  return <div
    css={css`
      ${Foo} {
        background: #f00;
      }
    `}
  >
    <Foo>FOO</Foo>
  </div>;
};

在此示例中,我想设置 Foo 组件的样式,它是 div 的后代。

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

<div class="test__Foo-wusfqk-0 hNfawX">FOO</div>

然而,它只是:

<div>FOO</div>

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

另外,组件Foo只被渲染一次,却被调用了两次,参数不同:

{children: {…}, theme: {…}}
  children: {$$typeof: Symbol(react.element), key: null, ref: null, props: {…}, type: ƒ, …}
  theme: {}

{children: "FOO"}

我应该提到我尝试过:

// @flow

import React from 'react';
import styled, {
  css,
} from 'styled-components';

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

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

export default () => {
  return <div
    css={css`
      ${Foo} {
        background: #f00;
      }
    `}
  >
    <Foo>FOO</Foo>
  </div>;
};


但是,在 中执行此代码时,出现以下错误:

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

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

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

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

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

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

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

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

考虑到主题代码 sn-p,这没有多大意义。

【问题讨论】:

  • 您是否尝试过使用styled?
  • 刚刚添加了关于使用styled的评论。
  • 你能把它发布为代码沙箱吗?
  • 请注意,styled-components 似乎已经死了。我已经使用它很多年了,直到 v5 开始出现故障,没有任何修复。结果,我跳槽到@emotion/styled。它与 styled-components 非常相似,但它......只是有效。此外,它可以工作without a custom nextjs _document page!

标签: next.js javascript reactjs next.js styled-components


【解决方案1】:

主要问题是&lt;Foo /&gt; 不是样式组件,而是功能组件

我认为你需要这样做

const Foo = styled.div`
    background: #f00;
`

然后您可以使用css 和$ refrence 更改Foo 的样式

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

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

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

const B = styled.div`
  ${Foo} {
  }
`

但是,将 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;
  }
`

代码沙盒

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"));

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

【讨论】:

  • 这个问题具体是关于使用功能组件,而不是样式组件。根据文档,上面的示例应该可以工作。 styled-components.com/docs/advanced(参见className 参考资料)。
  • @Gajus 您需要查看文档的末尾,它解释了为什么您不能在样式化组件 css 中引用函数或类组件
  • 你说得对,我的问题已经包含了一个使用styled(Foo) 包装组件的示例,并表明它不能按预期工作。
  • 这确实有效。谢谢你帮我弄清楚。
  • 另外,我很确定 css 帮助器仅设计用于基于字符串、CSSProperties 或带有 props 的插值函数生成样式。它不是为组件选择器设计的。相反,正如 Omar 所提到的,它只能在 styled 上下文中使用。
猜你喜欢
  • 2021-04-13
  • 2021-04-21
  • 1970-01-01
  • 2020-06-29
  • 2021-04-13
  • 2021-08-12
  • 2021-03-08
  • 2019-03-03
  • 2020-11-19
相关资源
最近更新 更多