ThemePicker 컴포넌트


- 공통 컴포넌트, 테마를 선택할 수 있도록 하는 컴포넌트
- 명상 테마 외에도 nav 처럼 특정 채널을 선택할 수 있도록 하는 용도로 쓰일 수 있다고 생각하여, 재사용성을 위해 공통 컴포넌트로 관리하고 있습니다. (현재는 페이지 두곳에서 사용)
- 데이터를 prop 으로 받아 데이터에 따른 버튼들을 출력해주고 있습니다.
import themeInfoData from './model'; const Parent = () => { return ( <ThemePicker themeInfoData={themeInfoData} /> <Sibling /> ) }
문제 상황
ThemePicker 에서 특정 테마를 선택하면 선택된 테마를 부모 컴포넌트가 다른 형제 컴포넌트에게 전달을 해줘야 하는 상황입니다.

여기서 형제 컴포넌트에게 변경사항을 알리는 방법으로 두가지 방법이 나왔습니다.
- 전역 상태로 ThemePicker 의 상태를 관리하자! (창기)
- state 를 변경하는 prop 을 전달하자! (수연)
1. 전역상태로 전달
현재는 아래와 같이 ThemePicker 내에서 특정 특정 state 를 불러와서 변경해주고 있습니다.
// ThemePicker import { themeState } from '@state/theme'; import { useRecoilState } from 'recoil'; const ThemePicker = () => { const [theme, setTheme] = useRecoilState(themeState); }
- 수연이 생각하는 문제점
- ThemePicker 컴포넌트가 특정 전역 데이터에 의존하게 되면 ThemePicker 에 종속성이 생겨서 다른 데이터로 ThemePicker 를 만들기 어려워지지 않을까요? (재사용의 문제)
그래서 어떤 전역 상태를 참조할 지 상위 컴포넌트에서 정해주는 방법을 대안으로 생각해보기도 했습니다.
// Parent import { themeState } from '@state/theme'; const Parent = () => { return ( <ThemePicker state={themeState} themeInfoData={themeInfoData} /> <Sibling /> ) }
- 수연이 생각하는 문제점
- 전역 상태를 prop 으로 관리하면 혹시 전역 상태로 관리해주는 의미가 없어지진 않을까요?
- 만일 다른 ThemePicker 를 만든다고 하면 그때마다 전역 상태를 만들어서 관리해줘야 하지 않을까요? (같은 전역 상태를 공유하면 사이드 이펙트 발생 가능성)
2. prop 으로 전달
ThemePicker 에서 특정 데이터가 선택된 경우 상위 state 를 변경시키는 방법입니다.
- 수연, 창기가 생각하는 문제점
- 어떤 컴포넌트가 다른 컴포넌트의 상태를 변경시키는 setter 함수를 prop으로 받거나 내려주는 패턴은 지양해야할 패턴입니다!
const Parent = () => { const [theme, setTheme] = useState(); const handleChangeTheme = (event) => { setTheme(event.target.value )}; return ( <ThemePicker onChange={handleChangeTheme} /> <Sibling theme={theme} /> ) }
3. 멘토님께 여쭤보고 싶은 것
- 어떻게 ThemePicker 에서 선택한 state 를 형제 컴포넌트에게도 전달할 수 있을까요?
- 어떤 방법이 ThemePicker 의 재사용성을 해치지 않으면서도 불필요한 전역 상태를 만들지 않을 수 있을까요?
by

- 우선 전역상태로 관리하는것은 그다지 좋은 방법은 아닌것 같습니다.
- ThemePicker의 onClick, onChnage 등의 핸들러이벤트를 등록시켜서 해당 컴포넌트를 사용하는 페이지에서 값을 받아서 처리할수 있도록 하는것이 좋을것 같습니다.
그리고 ThemePicker라기보다는 가로네비게이션정도의 컴포넌트로써 기능동작하게하고 그 세부처리에 대해서는 각각의 페이지에서 의미에따라 사용하는것이 더 좋지않을까요?
그리고 저거 이름이
theme
라고 되어있던데 테마의 성격을 띄고있는부분이 맞는걸까요? - 2번안으로 하되, ThemePicker, Sibling이 서로 유기적으로 묶여서 동작되는 형태인것 같습니다. 이 경우 해당 컴포넌트에서의 전역상태를 만들어서 관리하는 형태로 가능할것 같습니다.