Дочерние компоненты не отображаются - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь создать флип-карту с ReactJS, которая имеет внутри 2 других компонента: Frontside и BackSide. Эти компоненты должны иметь дочерние элементы, такие как BackgroundCard или Sectioned Card. Когда я тестирую компонент, на экране ничего не появляется, и в консоли нет ошибок!

FlipContent. js

function FlipContent() {
    const [setFront, setFrontState] = useState(true);
    const [setBack, setBackState] = useState(false);
    const [setFlipped, setFlippedState] = useState("");


    function FlippingCard() {

        setFrontState(setFront === true ? false : true);
        setBackState(setBack === false ? true : false);
        setFlippedState(setFlipped === "" ? "flipped" : "");

    }



    return (

        <div className={`flip-content ${setFlipped}`} onClick={FlippingCard} >
            <div className="flip-content-container" style={{ cursor: "pointer" }}>
                {setFront ? <FrontSide></FrontSide> : null}
                {setBack ? <BackSide> </BackSide> : null}
            </div>
        </div>
    );

}

И для FrontSide / BackSide то же самое, что и этот код

function FrontSide({ children }) {

    return (

        <div className="flip-content-front">
            <div style={{ cursor: "pointer" }}>
                {children}
            </div>
        </div>
    );

}

и вот как я пытаюсь просмотреть компонент

function FlipPreview() {
    return (
        <Column>
            <Row className={css(styles.title)} wrap flexGrow={1} horizontal="space-between" breakpoints={{ 768: 'column' }}>
                Accordion <br></br>
            </Row>
            <FlipContent>
                <FrontSide>
                    <CardBackgroundComponent title="Testing" image={image}></CardBackgroundComponent>
                </FrontSide>
                <BackSide>
                    <SectionedCardComponent
                        title="Notarum Black"
                        content="Powerful and reliable, this 15” HD laptop will not let you down. 256GB SSD storage, latest gen."
                        link=""
                        linkDescription="Add To Cart"
                    />
                </BackSide>
            </FlipContent>
        </Column>
    );
}

Ответы [ 2 ]

1 голос
/ 07 января 2020

Так что в вашем компоненте вы не рендерите детей. Поэтому вам нужно обновить две вещи.

1) Взять реквизиты в компоненте FlipContent, как показано ниже

function FlipContent(props)

2) Использовать реквизиты при рендеринг внутри компонента, как показано ниже

 {setFront ? <FrontSide>{props.children}</FrontSide> : null}
  {setBack ? <BackSide>{props.children} </BackSide> : null} 

проблема на втором шаге в том, что он загрузит все реквизиты дочерних элементов, поэтому вам нужно отрендерить только указанный компонент c. См. Ниже

Обновление

Существует несколько способов решения этого вопроса: один за другим

решение один

Используя опору имени детей

function FlipContent(props) {
  const [view, setView] = useState("FrontSide");
  function FlippingCard() {
    setView(view === "FrontSide" ? "BackSide" : "FrontSide");
  }

  const component = React.Children.map(props.children, child => {
    if (view === child.type.name) {
      return child;
    }
  });

  return (
    <div className={`flip-content`} onClick={FlippingCard}>
      <div className="flip-content-container" style={{ cursor: "pointer" }}>
        {component}
      </div>
    </div>
  );
}

Работающий codesandbox

Решение Два

Вместо статического добавления имена можно выводить из опора, это не может обрабатывать один и тот же компонент несколько раз

function FlipContent(props) {
  const [view, setView] = useState(props.children[0].type.name);
  const ref = useRef(0);
  function FlippingCard() {
    if (props.children.length - 1 === ref.current) {
      ref.current = 0;
      setView(props.children[0].type.name);
      return;
    }
    setView(props.children[ref.current + 1].type.name);
    ref.current += 1;
  }
  let component = <span />;
  React.Children.forEach(props.children, child => {
    if (view === child.type.name) {
      component = child;
      return;
    }
  });

  return (
    <div className={`flip-content`} onClick={FlippingCard}>
      <div className="flip-content-container" style={{ cursor: "pointer" }}>
        {component}
      </div>
    </div>
  );
}

Работающий codesandbox

Решение три

Рендеринг нескольких компонентов и в одной оболочке сам по себе.

function FlipContent(props) {
  const [component, setComponent] = useState(props.children[0]);
  const ref = useRef(0);
  function FlippingCard() {
    if (props.children.length - 1 === ref.current) {
      ref.current = 0;
      setComponent(props.children[0]);
      return;
    }
    setComponent(props.children[ref.current + 1]);
    ref.current += 1;
  }

  return (
    <div className={`flip-content`} onClick={FlippingCard}>
      <div className="flip-content-container" style={{ cursor: "pointer" }}>
        {component}
      </div>
    </div>
  );
}

Работающий codesandbox

Мне кажется, решение три является самым простым, и у вас есть масштабируемый способ.

1 голос
/ 07 января 2020

Я думаю, что вы не вставили что-то внутри обоих компонентов FrontSide, BackSide

   <div className={`flip-content ${setFlipped}`} onClick={FlippingCard} >
      <div className="flip-content-container" style={{ cursor: "pointer" }}>
        {setFront ? <FrontSide> It's front side </FrontSide> : null}
        {setBack ? <BackSide> It's back-side </BackSide> : null}
       </div>
    </div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...