React에서 JSX는 함수 실행 결과로 렌더링되기 때문에, 종종 예상치 못한 동작이 발생할 수 있습니다.
특히 컴포넌트 내부에 early return이 존재할 경우, JSX 상에는 존재하는 컴포넌트가 실제 화면에서는 렌더링되지 않는 상황이 발생합니다.
다음과 같은 코드가 있다고 가정합니다.
<Flex direction='col' gap='gap-y-[20px]'>
<CreatorBrowse />
<GameCommunityBrowse />
<CreatorsCampaign />
<CampaignBrowse />
<RankingBrowse />
<BottomBanner />
</Flex>
해당 코드로 렌더링 된 페이지는 다음과 같습니다.
해당 코드는 페이지를 블럭 단위로 구성한 간단한 예제입니다.
코드와 렌더링된 페이지를 유추해보면, <CampaignBrowse />
는 분명 JSX로 렌더링이 명시되어 있지만, 실제 페이지에는 렌더링되지 않습니다.
이는 해당 컴포넌트 내부에서 조건에 따라 null을 반환하는 early return 로직 때문입니다.
위 예제 코드는 블럭 단위로 페이지를 쌓았기에 비교적 파악이 쉽지만, 조금 더 복잡한 코드에서는 파악이 더욱 어려워집니다.
CampaignBrowse 컴포넌트의 내부는 다음과 같습니다.
const CampaignBrowse = () => {
const data = use데이터핸들링hook();
const a = use또다른hook1();
const b = use또다른hook2();
if (data.length === 0) return null;
return <div>...</div>;
};
이 코드는 다음과 같은 문제를 일으킵니다.
렌더링 조건을 Page 컴포넌트에서 관리하도록 개선할 수 있습니다.
const Page = () => {
const data = use데이터핸들링hook();
const isCampaignBrowseRender = data.length !== 0;
return (
<Flex direction='col' gap='gap-y-[20px]'>
<CreatorBrowse />
<GameCommunityBrowse />
<CreatorsCampaign />
{isCampaignBrowseRender && <CampaignBrowse />}
<RankingBrowse />
<BottomBanner />
</Flex>
);
};
const CampaignBrowse = () => {
const data = use데이터핸들링hook();
const a = use또다른hook1();
const b = use또다른hook2();
return <div>...</div>;
};
이렇게 하면 CampaignBrowse가 렌더링될지 여부를 외부에서 명확하게 판단할 수 있습니다.
그러나 이 방식은
라는 한계를 가집니다.
렌더링 여부에 필요한 로직을 별도의 컴포넌트로 분리하고, Function as Child 패턴을 활용합니다.
const Page = () => {
return (
<Flex direction='col' gap='gap-y-[20px]'>
<CreatorBrowse />
<GameCommunityBrowse />
<CreatorsCampaign />
<CampaignBrowseRenderProvider>
{({ isRender }) => isRender && <CampaignBrowse />}
</CampaignBrowseRenderProvider>
<RankingBrowse />
<BottomBanner />
</Flex>
);
};
const CampaignBrowseRenderProvider = ({
children,
}: {
children: ({ isRender }: { isRender: boolean }) => React.ReactNode;
}) => {
const data = use데이터핸들링hook();
const isRender = data.length !== 0;
return children({ isRender });
};
컴포넌트 단위의 책임을 분리하고 렌더링 조건을 명확하게 관리하는 방식은 규모가 커질수록 더욱 빛을 발한다고 생각합니다.
단순한 개선처럼 보일 수 있지만, 이러한 패턴은 실제 개발 생산성과 유지보수성에 큰 영향을 미칩니다.
다른 의견이나 더 좋은 방안이 있다면 댓글 작성해주시면 감사드리겠습니다.