对象作为具有样式化组件的 React 子项无效

Objects are not valid as a React child with Styled components

我正在尝试渲染图像。这是我的代码:

Accordion.jsx

import React from 'react';
import ArrowTemplate from "./ArrowTemplate";

function Accordion() {
    return (
        <div>
            <ArrowTemplate arrowType={"BlackDown"} styles={""}/>
            {/*<ArrowTemplate arrowType={"BlackUp"}/>*/}
            {/*<ArrowTemplate arrowType={"WhiteDown"} styles={"background:black"}/>*/}
            {/*<ArrowTemplate arrowType={"WhiteUp"} styles={"background:black"}/>*/}
        </div>
    );
}

export default Accordion;

ArrowTemplate.jsx

import BlackDownArrowSVG from './svgs/black-down-arrow.svg';
import WhiteDownArrowSVG from './svgs/white-down-arrow.svg';
import styled from 'styled-components';
import PropTypes from 'prop-types';

ArrowTemplate.propTypes = {
    arrowType: PropTypes.string,
    styles: PropTypes.string,
};

function ArrowTemplate(props) {
    const {arrowType, styles} = props;
    switch (arrowType) {
        case "WhiteDown":
            return (
                styled.img.attrs({
                    src: WhiteDownArrowSVG,
                })`${styles !== null ? styles : ""}`
            );
        case "BlackDown":
            return (
                styled.img.attrs({
                    src: BlackDownArrowSVG,
                })`${styles !== null ? styles : ""}`
            );
        case "WhiteUp":
            return (
                styled.img.attrs({
                    src: WhiteDownArrowSVG,
                })`transform: rotate(180deg); ${styles !== null ? styles : ""}`
            );
        case "BlackUp":
            return (
                styled.img.attrs({
                    src: BlackDownArrowSVG,
                })`transform: rotate(180deg); ${styles !== null ? styles : ""}`
            );
        default:
            throw("You need to pass arrowType");
    }
}

export default ArrowTemplate;

SVG 路径正确。

作为我得到的错误:

Objects are not valid as a React child (found: object with keys {$$typeof, render, displayName, attrs, componentStyle, foldedComponentIds, styledComponentId, target, withComponent, warnTooManyClasses, toString}). If you meant to render a collection of children, use an array instead. in ArrowTemplate (at Accordion.jsx:7)

当我 console.log 我得到一个长对象。但是当我 console.log 来自 docs:

的示例代码时,我得到了一个类似的对象
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

//^^^^^^^^^^^^^^^^^^^^^
//This renders with no problem

我哪里错了?

尝试:

import BlackDownArrowSVG from './svgs/black-down-arrow.svg';
import WhiteDownArrowSVG from './svgs/white-down-arrow.svg';
import styled from 'styled-components';
import PropTypes from 'prop-types';

ArrowTemplate.propTypes = {
    arrowType: PropTypes.string,
    styles: PropTypes.string,
};

function ArrowTemplate(props) {
    const {arrowType, styles} = props;
    let StyledArrowTemplate;

    switch (arrowType) {
        case "WhiteDown":
          StyledArrowTemplate = (
            styled.img.attrs({
                src: WhiteDownArrowSVG,
            })`${styles !== null ? styles : ""}`
          );
        break;
        case "BlackDown":
          StyledArrowTemplate = (
            styled.img.attrs({
                src: BlackDownArrowSVG,
            })`${styles !== null ? styles : ""}`
          );
        break;
        case "WhiteUp":
          StyledArrowTemplate = (
            styled.img.attrs({
                src: WhiteDownArrowSVG,
            })`transform: rotate(180deg); ${styles !== null ? styles : ""}`
          );
        break;
        case "BlackUp":
          StyledArrowTemplate = (
            styled.img.attrs({
                src: BlackDownArrowSVG,
            })`transform: rotate(180deg); ${styles !== null ? styles : ""}`
          );
        break;
        default:
            throw("You need to pass arrowType");
    }

    return <StyledArrowTemplate />;
}

export default ArrowTemplate;

编辑:

对于最初缺乏解释的缺乏表示歉意!

所以出现此错误的原因是当您 return 在 JSX 代码中使用某种对象时。在本例中为 styled.img.attrs。因此,为了解决这个问题,我们声明一个变量,然后将其设置为其中一种情况下的样式组件,具体取决于您提供给 ArrowTemplate 组件的道具,以及 return 它在函数结束。

这样,您基本上可以像往常一样创建一个 StyledComponent,但是以动态方式创建的。

Lindsay 的上述回答可能没问题,但我认为不使用 switch case 更有意义,而是 return 单个组件并将您的条件作为 props 传递,执行您的条件逻辑在样式化组件的定义中,即类似于...

const ArrowTemplate = styled.div`
  src: ${props => props.color === Black ? BlackDownArrowSVG : WhiteDownArrowSVG};
  ${props => props.direction === Down ? transform: rotate(180) : null }
  etc...
`;

(不确定我上面的语法是否完全正确,但这是基本思想)

<ArrowTemplate color={Black} direction={Up} src={src} /> 

如果您在声明样式化组件时遇到这种情况,您可能忘记了声明末尾的模板文字。所以

const AppContentWithSideBar = styled((props) => {
  return (
    <Wrapper>
      <Router>
        <SideBarWrapper>
          <SideBar />
        </SideBarWrapper>
        <MainWrapper>
          {props.children}
        </MainWrapper>
      </Router>
    </Wrapper>
  );
});

应该是

const AppContentWithSideBar = styled((props) => {
  return (
    <Wrapper>
      <Router>
        <SideBarWrapper>
          <SideBar />
        </SideBarWrapper>
        <MainWrapper>
          {props.children}
        </MainWrapper>
      </Router>
    </Wrapper>
  );
})``;
const Button = styled.button`
    font: inherit;
    padding: 0.5rem 1.5rem;
    border: 1px solid #8b005d;
    color: white;
    background: #8b005d;
    box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
    cursor: pointer;
`

您收到此错误是因为您将值存储在函数而不是变量中。让我举个例子让你知道。

这对你有用。