[React] children Component에 props 전달하기

HyunJoo·2021년 12월 19일
13

react

목록 보기
2/2
  1. props로 component를 전달할 때 children으로 넘겨라
  2. children에 props를 넣어서 전달하고 싶다면 React.cloneElement를 사용하라

1. props로 component를 전달할 때 children으로 넘겨라

Layout을 만들어서 Component를 전달해야 하는 경우가 있다.
즉, Content만 변경하는 것이다.

아래와 같은 식으로

const App = () => {
  const content = <Content/>
  return (
      <ModalLayout isOpenModal={isOpenModal} setContent={setContent}>
        {content}
      </ModalLayout>
  )
}

const ModalLayout = ({children}) => {
  return (
    <ModalBox>{children}</ModalBox>
  )
}
  1. 상위 컴포넌트 사이에 하위 컴포넌트로 넘기고 싶은 컴포넌트를 넣어준다.
  2. 상위 컴포넌트에 대해 정의할 때 props에 children을 받고 render 부분에 children을 호출한다.

왜?

먼저 리액트가 render할 때 코드를 어떻게 변환하는지 알아야 한다.
react는 React.createElement(component, props, ...children)를 이용하여 변환을 한다.

예시코드

<ModalLayout isOpenModal={isOpenModal} setContent={setContent}>
        {content}
      </ModalLayout> // 이 코드를 아래와 같이 사용한다.
      
React.createElement(ModalLayout, {isOpenModal:isOpenModal, setContent:setContent}, content)

props는 객체형태로 children까지 전달된다.


콘솔을 찍어보면 이렇게 나온다.

그러므로 자식컴포넌트에서 props.children 또는 props.isOpenModal로
상위컴포넌트에서 넘겨주는 props를 이용가능하다.

리액트 공식문서 : JSX 이해하기 자세한 내용이 있다.

2. children에 props를 넣어서 전달하고 싶다면 React.cloneElement를 사용하라

이제 Layout에서 전달받은 children에 props를 추가해서 render하는 방법을 알아보자
위의 방식처럼 createElement를 사용하여 진행하려고 했다.

const ModalLayout = (props) => {
  const {children, setContent, isOpenModal} = props;
  return (
    React.createElement(ModalBox, {setContent, isOpenModal}, children)
  )
}

하지만 아래와 같은 에러가 나왔다.


children 컴포넌트는 표시는 되었지만 props를 전달하지 못한 것
children에서 props를 console.log에 찍어보니 값이 없었다.

왜????

React.createElement(ModalBox, {setContent, isOpenModal}, children) 이 코드는 <ModalBox {...props}>{children}</ModalBox>와 같다. 잘못된 코드이다.

const ModalLayout = (props) => {
  const {children, setContent, isOpenModal} = props;
  return (
  <ModalBox>
    React.createElement(React.Fragment, {setContent, isOpenModal}, children)
  </ModalBox>
  )
}

이런 식으로 작성하면 될 줄 알았지만

React.createElement(type,[props],[...children])
type 인자로는 태그 이름 문자열('div' 또는 'span' 등), React 컴포넌트 타입, 또는 React Fragment 타입 중 하나가 올 수 있습니다.

props는 읽기 전용이라서 수정이 불가능하다고 하는데...
cloneElement를 사용하라고 한다.

리액트 공식문서 : cloneElement

const ModalLayout = (props) => {
  const {children, setContent, isOpenModal} = props;
  return (
    <ModalBox>
      {React.cloneElement(children, {setContent, isOpenModal})}
    </ModalBox>
  )
}

이렇게 사용하면 children의 props에 setContent, isOpenModal이 전달이 된다.

알게된 점

  1. React에서 작성한 코드가 컴파일할 때 babel에 의해 createElement로 변경이 되는지.
  2. createElement의 type, props, children의 전달 방법과 어떤 타입인지.
  3. props는 읽기 전용이다? (다시 검색필요)
  4. cloneElement로 children에 props 전달하기

참고 자료들

JSX 이해하기 : https://ko.reactjs.org/docs/jsx-in-depth.html

createElement와 cloneElement :
https://ko.reactjs.org/docs/react-api.html#createelement

https://www.geeksforgeeks.org/what-is-the-difference-between-createelement-and-cloneelement/

profile
Front-End Engineer

1개의 댓글

comment-user-thumbnail
2022년 2월 17일

와 덕분에 코드가 깔끔해졌어용

답글 달기