children을 갖는 콤포넌트의 작성

lee Samse·2024년 7월 4일

react-course

목록 보기
8/8
post-thumbnail

child 콤포넌트를 갖는 콤포넌트를 작성하는 경우에 children이라는 객체가 props로 전달되어져 오게 된다.


const Parent = (props) => {
	return <>{props.children}</>
}

const Child = () => {
	return <div><p>Hi i'm child</p></div>;
}

const Container = () => {
	return <>
		<Parent><Child></Parent>
	</>
}

Parent가 다른 콤포넌트를 품을수 있도록 하려면 위와 같이 할 수 있다.

Parent가 children을 품지 않고 바로 해당 콤포넌트를 리턴할수도 있을것이다.

const Parent = () => {
	return <><Child/></>
}

children을 사용하는 이유는 Parent가 다양한 콤포넌트를 포함할 수 있도록 하는 방법도 있곘으나 이를 적용하였을때 어떤 효과가 나타나는지 알아둘 필요가 있다.

children을 적용하였을때와 Parent에서 직접 Child를 렌더링할때 차이점은 Parent가 리렌더 될때 Child가 리렌더가 되는가의 차이이다.
children을 적용하였을 때는 Parent가 변경되어도 Child가 리렌더되지 않는다.

다음 예를 보자

const Child = () => {
    console.log("render child");
    return <div><p>I'm child</p></div>
}

const Parent = () => {
    console.log("render parent");
    const [value, setValue] = useState(false);
    return <div style={{display: "flex"}}><Child/>
            <button onClick={() => setValue(!value)}>다시그리기</button>
            </div>
}

const ParentWithChild = (props: any) => {
    const [value, setValue] = useState(false);
    console.log("render parent with children");
    return (
    <div style={{display: "flex"}}>
        {props.children}
        <button onClick={() => setValue(!value)}> 다시그리기 </button>
    </div>);
}

Parent와 ParentWithChild가 있고 ParentWithChild의 경우 Child를 직접 내포하지 않고 있다.

<div>
    <Parent/>
    <br/>
    <ParentWithChild>
        <Child />
    </ParentWithChild>
</div>

Parent의 다시그리기 버튼을 누르면 다음과 같이 로그가 나온다.

render parent
render parent
render child
render child

ParentWithChild의 다시그리기 버튼을 누르면 다음과 같이 로그가 나온다.

render parent with children
render parent with children

두 방식의 차이점은 children방식을 사용하면 child가 parent가 변경되어도 render가 발생하지 않는 다는 것이다. 이는 앱의 전체적인 성능에 영향을 줄 수 있는 중요한 점이다.

React.memo를 사용하면 콤포넌트의 props가 변경되지 않는 한 다시 렌더링되지 않도록 할 수 있다. 이는 부보콤포넌트가 변경될때 자식의 props가 변경되지 않는 경우 사용하면 렌더링성능의 향상시키기 위한 방법으로 많이 사용된다.

그런데 콤포넌트가 children을 사용한다면 이 공식이 꺠지게 된다.
이유는 children자체가 매번 새로 생기기 때문이다.
따라서 children을 사용할것인지 말지는 잘 결정해서 적용해야 할것이다.

const Parent2 = (props: any) => {
    console.log("render parent2");
    return (<div>        
        {props.children}
    </div>);
}

const TestPage = () => {
    const [value, setValue] = useState(false);
    console.log("render Container");
    const NewParent = React.memo(Parent2);
    return (<div>
        <NewParent>
            <Child />
        </NewParent>
        <button onClick={() => setValue(!value)}> 전체 다시그리기 </button>
    </div>);
}

위 예에서 Parent2를 React.memo로 NewParent로 변경하여 적용하는 이유는 TestPage가 렌더링될때 Parent2의 props가 변경되지 않으면 렌더링되지 않도록 하기 위해서 적용할것이다. 따라서 전체 다시그리기 버튼을 누르면 "render Container" 로그만 찍힐것으로 예상하겠지만 실제로는 "render parent2"도 찍히게 된다.

profile
삼스입니다.

0개의 댓글