오늘은 zustand에서 발목이 잡혀서 한참을 zustand과제를 하는 데에 사용했다. 강의 들으면서 코드를 봤을 때도 느꼈는데, 이전에는 간단했던 zustand가 Next.js로 오면서 많이 어려워진 것 같다. 특히 type script로 값의 타입을 설정해두어야 한다는 것이 너무 큰 난관이었다.
아래는 우여곡절 끝에 완성한 zustand store 코드이다. 보다시피 타입 선언만 3번을 하고, 처음쓰는 주제에 이렇게 선언한 타입을 어떻게 줄일 수 없을까하다가 크게 코드가 꼬여서 튜터님의 안내를 받아 type 정리를 다시 할 수 있었다.
export interface CountProps {
count: number;
}
export interface CountState extends CountProps {
plusCount: () => void;
minusCount: () => void;
resetCount: () => void;
}
export type CountStore = ReturnType<typeof createCountStore>;
export const createCountStore = (initProps: Partial<CountProps>) => {
const DEFAULT_PROPS: CountProps = {
count: 0,
};
return createStore<CountState>()((set) => ({
...DEFAULT_PROPS,
...initProps,
plusCount: () => set((state) => ({ count: state.count + 1 })),
minusCount: () => set((state) => ({ count: state.count - 1 })),
resetCount: () => set((state) => ({ ...initProps })),
}));
};
또 보면 CountStore라는 처음보는 형태의 구조를 가진 타입은 이 코드 내에서 쓰이지 않는데, 이건 여기서 만든 함수(createCountStore)의 결과값의 타입을 ZustandProvider에서 가져가서 사용할 수 있도록 하는 것이다.
아래 코드를 보면
const storeRef = useRef<CountStore>()
라는 곳에서 <CountStore>라는 타입을 가져와서 사용하는 데 이는 이후에
storeRef.current = createCountStore(props)
에서 함수(createCountStore)를 가져다가 쓰기 때문이다.
"use client";
import { CountState, CountStore, createCountStore } from "@/countStore";
import React, { useContext, useRef } from "react";
import { createContext } from "react";
import { useStore } from "zustand";
export const CountContext = createContext<CountStore | null>(null);
export function useCountContext<T>(selector: (state: CountState) => T): T {
const store = useContext(CountContext);
if (!store) throw new Error("Missing CountContext.Provider in the tree");
return useStore(store, selector);
}
export function CountProvider({
children,
...props
}: React.PropsWithChildren<{ count: number }>) {
const storeRef = useRef<CountStore>();
if (!storeRef.current) {
storeRef.current = createCountStore(props);
}
return (
<CountContext.Provider value={storeRef.current}>
{children}
</CountContext.Provider>
);
}
이외에도 DEFAULT_PROPS와 initProps가 무엇인지에 대한 인식이나 아래 부분의 CountState 타입에 CountProps 타입이 포함되어 있다는 것에 대한 이해 등이 부족해서 과제가 힘들었다.
export interface CountState extends CountProps {
plusCount: () => void;
minusCount: () => void;
resetCount: () => void;
}
아무래도 js 환경에서도 코드리딩 능력이 부족했던 것이, ts 환경에 적응하는 과정에서도 코드리딩이 부족한 결과로 이어진 것 같다. 하지만 결국 어찌저찌 코드리딩에 성공한 것을 보니, 차분하게 살펴보면 못할 것도 없을 것이다. 아무래도 코드리딩 능력을 향상시키기 위해서 다른 사람의 코드를 살펴보거나 하는 등의 과정이 더 필요할 것 같다.
'til' 카테고리의 다른 글
Next.js입문 5일 차 @개인 과제 55% (1) | 2024.10.01 |
---|---|
Next.js입문 4일 차 @본격 시작, route handler (1) | 2024.09.30 |
Next.js입문 2일 차 @fetch, json-server-auth (0) | 2024.09.26 |
Next.js입문 1일 차 @라우팅, 렌더링, assets 최적화 (1) | 2024.09.25 |
타입 스크립트 + Next.js 입문 (2) | 2024.09.24 |