분류 Reactjs

하위 Props 및 컨텍스트 API를 사용하여 React 구성 요소 빌드

컨텐츠 정보

  • 조회 323 (작성일 )

본문

React는 컴포넌트를 구성하기 위한 여러 가지 강력한 패턴을 제공합니다. 

예를 들어, Containment, 전문화 및 렌더 Props. 오늘 우리는 표면에서 이해하기 쉬운 인터페이스처럼 보이는 Containment 패턴에 대해 알아볼 것입니다. 


https://blog.soshace.com/en/javascript/building-react-components-using-children-props-and-context-api/ 


그러나 React 문서에서 제공되는 예제에는 부모 컨테이너에서 해당 컨테이너로 데이터를 전달하는 방법에 대한 명시적인 설명이 없습니다. 어린이. 누가 알겠는가-이것은 React 인터뷰 질문을 풀 때 도움이 될 것입니다!


다음은 React docs 예제의 코드 스니펫으로 메모리를 새로 고칩니다.


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}
function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}


FancyBorder 구성 요소의 “color” prop을 하위 항목으로 전달해 보겠습니다.


언뜻보기에 분명하지 않습니다. 예제의 마크업에서 볼 수 있는 유일한 것은 불투명 한 소품처럼 보이는 {props.children}입니다. 그것으로 작업하는 것도 간단하지 않습니다. 그러나 여기에 React가 있습니다. React 문서는 특별한 섹션을 제공합니다.


React.Children 


가장 먼저 필요한 것은 React.Children.map (children)입니다. 컴포넌트가 하나만 있으면 기본적으로 배열이 아니기 때문에 자식을 항상 배열로 처리합니다. 다음으로 사용해야 할 것은 React.cloneElement (element, props)입니다. React.cloneElement (element, props)는 모든 React 요소가 불변이라는 사실을 해결하는 데 사용됩니다. 마지막으로 다음 코드를 만들 수 있습니다.


const FancyBorder = ({ children, color }) => {

  const childrenWithProps = React.Children.map(children, element =>

    React.cloneElement(element, { style: { color } })

  );

 

  return (

     <div className={'FancyBorder FancyBorder-' + props.color}>

          {childrenWithProps}

     </div>;

}


이제 FancyBorder 내부의 모든 자식은 부모 구성 요소에서 전달 된 "색상"소품을 받습니다. FancyBorder 상위 컴포넌트에서 모든 하위 컴포넌트로 "color"소품을 전달하는 대신 최상위 레벨에 단순히 "color"를 추가 할 수 있음을 인정할 수 있습니다. 맞아요. 그러나 부모 소품을 활용할 수 있는 경우가 있습니다. 예를 들어 부모 소품을 기반으로 자식 소품을 계산해야 하는 경우가 있습니다.


예를 들어 "유형"이름 만 소품으로 사용하고 모든 하위 항목에 대해 이 유형을 기반으로 특정 스타일을 제공하는 테마 구성 요소를 가질 수 있습니다.


React.Children과 테마 


다음 코드를 고려해 봅시다.


const Theme = ({ children, type }) => {

  const style = type === "day" 

      ? { color: "black", background: "white" } 

      : { color: "white", background: "black" }

  const themedChildren = React.Children.map(children, element =>

    React.cloneElement(element, { style })

  );

 

  return themedChildren;

}

 

<Theme type="day">

     <h1>Welcome!</h1>

     <div>Some text inside</div>

</Theme>


이 예제의 모든 어린이는 부모의 "유형"소품에 따라 색상과 배경이 있습니다. 그 외에도 코드는 재사용 하기 쉽습니다. 모든 어린이를 테마 컴포넌트로 감싸면 테마가 됩니다.


React.Children toggler 


구성이 전혀 없는 "포장 만하면 작동"패턴이 너무 멋져서 동적 상태가 자식에 전달 된 구성 요소를 만들고 싶습니다. 가능합니까? 아래 코드에서 볼 수 있듯이 다음 마크업으로 버튼 클릭으로 콘텐츠를 전환 할 수 있는 간단한 인터페이스를 사용할 수 있습니까?


<Toggler>

  <button>toggle</button>

  <div>Content</div>

</Toggler>


믿어지지 않지만 가능합니다. 코드는 다음과 같습니다.


import React, { useState } from "react";

 

const Toggler = ({ children }) => {

  const [isVisible, setVisible] = useState(true);

  const renderChildren = React.Children.map(children, (el, index) => {

    if (index) return isVisible ? el : null;

    return React.cloneElement(el, { onClick: () => setVisible(!isVisible) });

  });

 

  return renderChildren;

};


이 예제의 코드는 전환기 버튼이 래퍼 내부의 첫 번째 요소 인 것으로 간주합니다. “type”또는“isToggler”와 같은 특정 요소 소품으로 토글러를 확인하면 요소의 순서를 변경하고 토글 기능을 계속 사용할 수 있습니다. 그런 다음 renderChildren 함수에서 index 대신 el.props.type을 확인해야 합니다. 콘텐츠의 경우 수정이 필요 없는 즉시 요소 복제가 필요하지 않으므로 코드는 요소를 렌더링 하거나 null을 반환합니다.