+) next.js 에서 Zustand persis 사용하기 (feat. Hydration error)
https://jjang-j.tistory.com/124
시작하며...
React 에서 다른 컴포넌트로 데이터를 전달하기 위해 props 를 사용한다.
그러나 React 의 상태인 state 는 자식 컴포넌트한테만 전달할 수 있어 만약 컴포넌트가 많고 잘 분리되어 있을 경우
state 를 전달하는데 매우 복잡하고 해당 state 를 사용하지 않는 컴포넌트로 받게 되어 비효율적인 코드가 되어 버린다.
그래서 이러한 경우를 해결하기 위해 상태 관리 라이브러리를 사용하며 그 종류로는 Redux
, Recoil
, Mobx
, Zustand
등이 있다.
나는 그 중에서 Zustand 에 대해 알아 볼 것이다.
Zustand
Zustand 란 무엇일까? 독일어로 상태
라는 뜻을 가지고 있다.
Zustand 는 패키지 크기가 작으며 사용하기 쉽다는 장점을 가지고 있다. 직접 사용하면서 얼마나 간단한지 알아볼 것이다.
설치하기
Zustand 를 사용하기 위해 해당 라이브러리를 설치한다.
npm install zustand
Store(스토어) 생성
create 로 store 생성
상태를 저장하고 관리하는 store
를 만들어 주기 위해 create
함수를 import 한다.
import { create } from 'zustand';
나는 편지를 작성하고 작성된 편지들을 리스트로 저장하여 관리할 것이다.
그래서 create
를 사용해 useLetterStore 라는 스토어를 생성한다. (TypeScript 로 작성함)
// letterStore.ts
interface letterState {
id: number;
title: string;
content: string;
}
interface letterListState {
letters: letterState[];
addLetter: (newLetter: { title: string; content: string }) => void;
}
export const useLetterStore = create<letterListState>((set) => ({
... 생략
}));
두 가지의 상태를 관리할 건데 첫 번째는 letters
로, 편지들의 리스트를 상태관리하며 초기값은 빈 배열이다.
다음으로 title과 content를 받아 객체를 생성하고 letters 배열에 추가하는 addLetter
를 만들었다.
set 으로 상태 업데이트
Zustand 에서 set
함수를 이용하여 상태를 업데이트 시킬 수 있고 현재 상태 state
를 인자로 받아
현재 상태에서 값을 업데이트 할 수 있다.
export const useLetterStore = create<letterListState>((set) => ({
letters: [],
addLetter: ({ title, content }) =>
set((state) => ({
letters: [
...state.letters,
{
id: state.letters.length + 1,
title,
content,
},
],
})),
}));
적용하기
store
에서 생성된 상태를 사용하기 위해 import 해준다.
import { useLetterStore } from '@/zustand/letterStore';
편지 작성하기
편지를 작성하고 편지 리스트에 추가하기 위해 useLetterStore
에서 addLetter
를 가져온다.
그리고 인자로 { title, content } 객체를 넣어준다.
const LetterForm = () => {
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
const { addLetter } = useLetterStore(); // addLetter
const handleSubmit = (e) => {
e.preventDefault();
addLetter({ title, content }); // addLetter
setTitle('');
setContent('');
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="제목"
/>
<input
type="text"
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="내용"
/>
<button type="submit">편지 추가</button>
</form>
);
};
편지 내용보기
편지 리스트의 상태를 가져오기 위해 useLetterStore
에서 letters
를 가져온다.
const LettersList = () => {
const { letters } = useLetterStore(); // letters
return (
<div>
{letters.map((letter) => (
<div key={letter.id}>
<h2>{letter.title}</h2>
<p>{letter.content}</p>
</div>
))}
</div>
);
};
결과
function LetterComponent() {
return (
<div>
<h1>편지 작성하기</h1>
<LetterForm />
<h1>편지 목록</h1>
<LettersList />
</div>
);
}
export default LetterComponent;
코드를 실행하면 아래 결과처럼 나오며
내용을 입력하여 편지 추가 버튼을 누르면 addLetter
로 인해 편지가 letters
에 추가되며,
letters
에 있는 내용이 보이게 된다.
+) 상태 가져오기
위에 코드를 보면 아래 코드처럼 store 에 있는 특정 상태를 가져왔다.
const { addLetter } = useLetterStore();
const { letters } = useLetterStore();
그러나 이렇게 하면 해당 상태만 가져오는 것이 아니라 상태를 모두 가져오는 것이기 때문에
다른 상태/액션이 변경될 경우 컴포넌트는 재렌더링을 발생한다.
그래서 특정 상태만 가져오기 위해서는 아래 코드처럼 작성해야 한다.
const addLetter = useLetterStore((state) => state.addLetter);
const letters = useLetterStore((state) => state.letters);
마치며...
이렇게 해서 Zustand 에 대해 알아보았다. 간단하게 사용하는 방법만 알아보았으며
더 자세한 설명을 보고 싶으면 Zustand 공식문서 에서 확인할 수 있다.
'💜 리액트 > 라이브러리' 카테고리의 다른 글
[React / CSS] 동적 조건부 스타일 지정 classNames 라이브러리 (0) | 2024.05.03 |
---|---|
[React] Zod로 React-Hook-Form 유효성 검증 (0) | 2024.03.05 |
[React] TanStack Query 에서 Suspense 사용 (+ ErrorBoundary) (2) | 2024.03.01 |
[React] TanStack Query(리액트 쿼리) V5 (1) | 2024.02.27 |
[React] Firebase 로그인 - Authentication (1) | 2024.01.03 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!