강원도지사
article thumbnail

이 익스텐션 2개 설치했습니다.

 

tsrafce

<typescript />
import React from 'react' type Props = {} const page = (props: Props) => { return ( <div>page</div> ) } export default page

usf

<typescript />
const [, set] = useState();

uef

<typescript />
useEffect(() => { }, []);

 

 

ZUSTAND 설치법

<typescript />
yarn add zustand

 

 

/src/app/zustand 폴더 생성 후 page.tsx 생성

<typescript />
import { create } from 'zustand' type Props = {} interface TestStore { count: number; increment: () => void; decrement: () => void; } //zustand는 전역 상태 관리 라이브러리 const useTestStore = create<TestStore>((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })) })); export default useTestStore

 

 

 

<typescript />
import { create } from 'zustand' type Props = {} interface TestStore { count: number; increment: () => void; decrement: () => void; } //zustand는 전역 상태 관리 라이브러리 const useTestStore = create<TestStore>((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })) })); const ZustandTestPage = (props: Props) => { const { count, increment, decrement } = useTestStore(); //useShallow로 사용하는 방법 찾아서 적용해보기 //useShallow 쓰는 이유 찾아보기 return ( <div className="flex gap-2 items-center"> <div>{count}</div> <button onClick={increment}>+</button> <button onClick={decrement}>-</button> </div> ); } export default ZustandTestPage;

 

 

useShallow 사용!! 

 

<typescript />
import { create } from 'zustand' import { shallow } from 'zustand/shallow' type Props = {} interface TestStore { count: number; increment: () => void; decrement: () => void; } //zustand는 전역 상태 관리 라이브러리 const useTestStore = create<TestStore>((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })) })); const ZustandTestPage = () => { // useShallow를 사용하는 방법 1: 객체 선택자와 함께 사용 // const { count, increment, decrement } = useTestStore( // (state) => ({ // count: state.count, // increment: state.increment, // decrement: state.decrement // }), // shallow // ); // useShallow를 사용하는 방법 2: 개별 선택자 사용 (권장) const count = useTestStore((state) => state.count); const increment = useTestStore((state) => state.increment); const decrement = useTestStore((state) => state.decrement); return ( <div className="flex gap-2 items-center"> <div>{count}</div> <button onClick={increment}>+</button> <button onClick={decrement}>-</button> </div> ); } export default ZustandTestPage;

 

useShallow를 쓰는 이유

1. 불필요한 리렌더링 방지

- 매번 새로운 객체가 생성되어 리렌더링 발생

- 얕은 비교를 통해 실제 값이 변경되었을 때만 리렌더링

2. 성능 최적화

- 객체의 얕은 비교를 수행

- 실제로 값이 변경되었을 때만 리렌더링 

- 메모리 사용량 감소

3. 메모리 효율성

-불필요한 객체 생성 방지

- 가비지 컬렉션 부하 감소

4. 예측 가능한 동작

- 상태 업데이트 시 컴포넌트의 리렌더링 시점을 더 정확하게 제어 가능

- 디버깅이 용이

 

 

터미널에 아래 코드 쳐서 다운로드 했습니다.

<typescript />
yarn add zod
<typescript />
yarn add react-hook-form

 

 

아예 싹 지우고 다시 작성함

<typescript />
'use client' import { create } from 'zustand' import { shallow } from 'zustand/shallow' import { useForm } from 'react-hook-form' import { z } from 'zod' import { zodResolver } from '@hookform/resolvers/zod' const ZodTestPage = () => { const schema = z.object({ name: z.string().min(1, "이름은 2글자 이상으로 적어주세요"), email: z.string().email("이메일 양식이 올바르지 않습니다."), }); const form = useForm<z.infer<typeof schema>>({ resolver: zodResolver(schema), defaultValues: { name: "", email: "", } }); const onSubmit = (values: z.infer<typeof schema>) => { console.log(values); }; return ( <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-2 p-4"> <input type='text' {...form.register("name")} placeholder="이름" className="border p-2 rounded" /> {form.formState.errors.name && ( <p className="text-red-500">{form.formState.errors.name.message}</p> )} <input type='text' {...form.register("email")} placeholder="이메일" className="border p-2 rounded" /> {form.formState.errors.email && ( <p className="text-red-500">{form.formState.errors.email.message}</p> )} <button type='submit' className="bg-blue-500 text-white p-2 rounded hover:bg-blue-600" > 제출 </button> </form> ); } export default ZodTestPage;

 

profile

강원도지사

@박강원입니다

노력하여 끊임없이 발전하는 사람이 되겠습니다!