Frontend/React

React.js - children에 props 전달

둉이 2022. 7. 4. 17:27

 

React에서는 컴포넌트 단독으로도 사용이 가능하지만 다른 컴포넌트를 감싸는 wrapper 컴포넌트로도 사용이 가능하다.

// 1. 컴포넌트 단독으로 사용
<LoadingSpinner />

// 2. wrapper 컴포넌트로 사용
<Layout>
  <SortingButton sort={sort} onClick={handleQuotes} />
  <AddForm onAddQuote={onAddQuote} />
</Layout>

 

wrapper 컴포넌트로 사용할 경우에는 해당 컴포넌트 내에 작성된 요소들은 children이라는 props로 컴포넌트에 전달된다.

 

wrapper 컴포넌트에서는 반드시 이 children을 리턴하는 마크업에 포함시켜야 화면에 노출된다.

const Layout = ({ children }) => {
  return <main className={styles.main}>{children}</main>;
};

 

만약 wrapper 컴포넌트를 사용하는 부모 컴포넌트가 아닌 wrapper 컴포넌트에서 전달받은 children에 추가적인 props를 더 전달하고자 할 때는 어떻게 하면 될까?

 

react의 cloneElement 함수를 이용하여 children 컴포넌트를 복사한 후, cloneElement의 두 번째 인자로 넘겨주고 싶은 props를 함께 전달하여 사용하면 된다.

const Layout = ({ children }) => {
  const childrenWithProps = Children.map(children, (child) => {
    if (isValidElement(child)) {
      return cloneElement(child, { 추가할_PROPS_이름: 'PROPS_값' });
    }
    return child;
  });

  return <div className={classes.card}>{childrenWithProps}</div>;
};

export default Layout;

 

주의할 점으로는 아래 예시처럼 컴포넌트를 div, ul 등의 별도의 태그로 감싸서 사용하는 경우에는 해당 태그에 props가 전달되므로 주의해야 한다.

// Layout에서 children에 props를 주입하면 SortingButton, QuoteItem이 아닌 Link(a), ul에 전달됨
<Layout>
  <Link to={`?sort=${sorts[sort]}`}>
    <SortingButton sort={sort} onClick={handleQuotes} />
  </Link>
  <ul className={classes.list}>
    {sortedQuotes?.map((quote) => (
      <QuoteItem key={quote.id} id={quote.id} author={quote.author} text={quote.text} />
    ))}
  </ul>
</Layout>

 

 

참고 자료

 

[javascript] 소품을 {this.props.children}에 전달하는 방법 - 리뷰나라

일반적인 방법으로 사용할 수있는 일부 구성 요소를 정의하는 올바른 방법을 찾으려고합니다. <Parent> <Child value="1"> <Child value="2"> </Parent> 물론 부모와 자녀 구성 요소 사이의 렌더링에가는 논리

daplus.net