state와 UI를 리턴하는 커스텀 훅이 필요해
우리에겐 state와 UI(컴포넌트)를 리턴하는 커스텀 훅이 필요합니다.
여기서 state는 전역상태로 관리되면 안되는 상황이므로
커스텀 훅에서 리턴하는 state 는 독립적이어야 합니다.
또한 비슷한 UI를 반복적으로 사용해야 하는데 렌더링해야하는
데이터종류는 2가지(여정테마/버디즈성향)인 상황입니다.
따라서 커스텀 훅의 리턴은 named export가 될 수 없으므로 객체가 아닌 배열어야 합니다.
그렇다면 [컴포넌트, 스테이트]
이렇게 반환하기만 하면 될 것 같습니다.
리턴할 컴포넌트
먼저 리턴할 컴포넌트를 atoms 레벨에 만들었습니다.
type PreferThemeProps = {
selectedTheme: string[];
handleThemeChange: (e: MouseEvent<HTMLSpanElement>) => void;
themes: (AllTripTheme | AllBuddyTheme)[];
label?: string;
};
const PreferTheme = ({
selectedTheme,
handleThemeChange,
themes,
label = '',
}: PreferThemeProps) => {
const id = useId();
return (
<>
{label && <label htmlFor={id}>{label}</label>}
<section id={id} className="flex flex-wrap gap-2">
{themes.map(theme => (
<Chip
key={theme.en}
selected={selectedTheme.includes(theme.ko)}
onClick={handleThemeChange}
intent={theme.en}
>
{theme.ko}
</Chip>
))}
</section>
</>
);
};
export default PreferTheme;
훅의 구조
그리고 훅의 구조는 다음과 같습니다.
type UsePreferThemeProps = {
themes: (AllTripTheme | AllBuddyTheme)[];
label?: string;
};
const usePreferTheme = ({
themes,
label,
}: UsePreferThemeProps): [() => ReactNode, string[]] => {
const [selectedTheme, setSelectedTheme] = useState<string[]>([]);
const handleThemeChange = (e: MouseEvent<HTMLSpanElement>) => {
const target = e.currentTarget;
const mutableThemes = themes.map(theme => theme.ko);
handleChipClick(target, mutableThemes, selectedTheme, setSelectedTheme);
};
const PreferThemeToRender = () => {
return (
<PreferTheme
selectedTheme={selectedTheme}
handleThemeChange={handleThemeChange}
themes={themes}
label={label}
/>
);
};
return [PreferThemeToRender, selectedTheme];
};
export default usePreferTheme;
이 훅은 객체형태의 인자로 두 가지를 받습니다.
먼저 themes 는 기준배열입니다.
우리 프로젝트에서는 여정테마배열전체 혹은 버디테마배열전체에 해당합니다.
타입도 만들어 두었습니다.
(튜터님 피드백에 따라 원데이터를 객체화 시켰으며 영어를 사용하기 위해 ko, en 두가지로 분리했습니다)
AllTripTheme 과 AllBuddyTheme 을 사용하면 됩니다.
다음으로 label 은 라벨입니다 ㅎㅎ
상단 라벨에 들어갈 텍스트로, 옵셔널하기때문에 전달하지 않으면 라벨이 생성되지 않습니다.
여정작성(글쓰기) 페이지에는 라벨이 없으므로 비워두시면 되겠습니다!
'nextjs' 카테고리의 다른 글
[240805 TIL] customAlert 개선 (0) | 2024.08.05 |
---|---|
[240731 TIL] Next.js Lazy Loading (0) | 2024.07.31 |
[240725 TIL] 다이나믹 헤더(middleware) (2) | 2024.07.25 |
[240717 TIL] Next.js Sharp (0) | 2024.07.17 |
[240716 TIL] NextJs Pwa (0) | 2024.07.16 |