- props로 component를 전달할 때 children으로 넘겨라
- children에 props를 넣어서 전달하고 싶다면
React.cloneElement
를 사용하라
Layout을 만들어서 Component를 전달해야 하는 경우가 있다.
즉, Content만 변경하는 것이다.
아래와 같은 식으로
const App = () => {
const content = <Content/>
return (
<ModalLayout isOpenModal={isOpenModal} setContent={setContent}>
{content}
</ModalLayout>
)
}
const ModalLayout = ({children}) => {
return (
<ModalBox>{children}</ModalBox>
)
}
먼저 리액트가 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 이해하기 자세한 내용이 있다.
이제 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를 사용하라고 한다.
const ModalLayout = (props) => {
const {children, setContent, isOpenModal} = props;
return (
<ModalBox>
{React.cloneElement(children, {setContent, isOpenModal})}
</ModalBox>
)
}
이렇게 사용하면 children의 props에 setContent, isOpenModal이 전달이 된다.
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/
와 덕분에 코드가 깔끔해졌어용