
function TestComponent({children, onClick}) {
return (
<div>
{children}
</div>
)
}
위 와 같이 children에 onClick 이라는 props로 넘어온 함수를 넘겨주고 싶은 일이 있었다.
이를 위해서 Context API를 이용하는 방법이 있었지만 하나의 Props만 관리하기엔 불필요한 코드를 작성하기도 번거롭고 Provider를 또 감싸야 하기 때문에 그럴 필요 없는 React의 API인 cloneElement 방식을 알게 되었다.
cloneElement를 이용해 기존 element에서 새로운 element를 만들고 기존과 다른 props를 전달이 가능하다.
하지만 공식 문서에 따르면 cloneElement를 사용하면 일반적이지 않고 불안정한 코드를 만들 수 있습니다. 라고 적혀있다. (데이터 흐름 추적이 어렵다는 문제)
이를 방지하기 위한 대안이 3가지를 제시하는데
이 있다. 여기서 나는 함수 단 하나, 심지어 엄청 간단한 작업을 하는 함수를 넘겨주어야 했기 때문에 rendering Prop를 사용하기로 마음먹었다.
render Prop을 사용하는 방법은 일반 Props를 넘겨주는것과 비슷하다. 단지 Props의 콜백 함수에 컴포넌트를 Return 해주면 된다.
<DataProvider render={data => (
<h1>Hello {data.target}</h1>
)}/>
공식 문서에 따르면 render prop은 컴포넌트 간에 코드를 공유하기 위해 함수 props를 이용하는 테크닉적인 기술을 말한다.
그렇다면 render prop을 이용하면 child 컴포넌트에 다른 컴포넌트의 데이터를 넘겨 줄 수 있다고 본다.
나는 메인 Component, render prop을 받는 RenderComponent, 이를 확인하기 위한 TestComponent 세가지를 두고 테스트를 해보았다.
먼저, RenderComponent는 prop으로 받아온 render에 handleClick이라는 함수를 넘겨주기 위해 아래와 같이 작성했다.
function RenderComponent ({render}) {
const handleClick = () => {
console.log('click')
}
return (
<>
{render({ handleClick })}
</>
)
}
그리고 MainComponent에서 RenderComponent에 테스트 하려는 TestComponet를 반환값을 가지는 render prop 함수를 설정하면 된다.
function MainComponent() {
return (
<div>
<RenderComponent render={( { handleClick }) => (
<TestComponent onClick={handleClick}/>
)} />
</div>
)
}
마지막으로 테스트 하려는 컴포넌트에서 평소와 같이 건네받은 prop을 사용하면 쉽게 RenderComponent에 있는 handleClick 함수를 context api와 custom hook을 작성하지 않고 간단하게 사용이 가능하다.
function TestComponent({ onClick }) {
return (
<div onClick={onClick}>
</div>
)
}