tl;dr
AS-IS
TO-BE
ReactNode를 외부에서 사용할 땐...
언제 테마 설정 Select 컴포넌트를 만들어야 하는 상황이 있었어요. 우리 테마 설정은 다크, 라이트만 있는게 아니라 시스템 옵션도 있어서 단순 토글 버튼이 아니라 Select로 구현했어야 했어요.
그래서 옵션 아이템들을 ReactNode
형태로 컴포넌트 밖에 선언을 해줬어요.
1// AS-IS 2const OptionItem = { 3 light: ( 4 <> 5 <SunIcon width="16px" /> 6 <span>라이트</span> 7 </> 8 ), 9 dark: ( 10 <> 11 <MoonIcon width="16px" /> 12 <span>다크</span> 13 </> 14 ), 15 system: ( 16 <> 17 <SettingIcon width="16px" /> 18 <span>시스템</span> 19 </> 20 ), 21};
그리고 Select 컴포넌트는 아래와 같이 만들어줬어요.
1// 해당 컴포넌트는 단순 예시에요. 2const Select = () => { 3 return ( 4 <select> 5 <option>{OptionItem.light}</option> 6 <option>{OptionItem.dark}</option> 7 <option>{OptionItem.system}</option> 8 </select> 9 ); 10};
근데 이렇게 하면 코드를 읽는 입장에서 저게 컴포넌트를 적어놓은건지, 그냥 단순 텍스트로 이루어진 데이터인지 알 수가 없어요. 그래서 render 메소드로 한 번 감싸주면 조금 더 명확하게 알 수 있어요.
1// TO-BE 2const OptionItem = { 3 light: { 4 render: () => ( 5 <> 6 <SunIcon width="16px" /> 7 <span>라이트</span> 8 </> 9 ), 10 }, 11 dark: { 12 render: () => ( 13 <> 14 <MoonIcon width="16px" /> 15 <span>다크</span> 16 </> 17 ), 18 }, 19 system: { 20 render: () => ( 21 <> 22 <SettingIcon width="16px" /> 23 <span>시스템</span> 24 </> 25 ), 26 }, 27};
위와 같이 선언을 해주고, 사용하는 곳에서는 확실하게 이건 리액트 컴포넌트를 렌더링 하는거야 라고 얘기할 수 있죠.
1// 조금 더 컴포넌트 같지 않나요? 2const Select = () => { 3 return ( 4 <select> 5 <option>{OptionItem.light.render()}</option> 6 <option>{OptionItem.dark.render()}</option> 7 <option>{OptionItem.system.render()}</option> 8 </select> 9 ); 10};
관련 포스트가 4개 있어요.
useSyncExternalStore가 무엇일까?
짧.
2023/10/23 (updated)
React 18 useSyncExternalStore에 대해서
CSS flex box의 align-items의 flex-start와 baseline의 차이점에 대해서
짧.
2023/09/24
CSS에서 align-items의 flex-start와 baseline의 차이점
React 18.0.0 react-dom의 flushSync의 사용법과 주의사항에 대해서 알아보자.
짧.
2023/09/24
React flushSync에 대해서
maxLength를 넣고 이모지를 넣으면 브라우저마다 계산되는 것이 다르다.
짧.
2023/09/15