CSS

[ CSS ] Zustand js와 ts로 사용해보기

yebeen 2024. 8. 22. 13:39

Zustand란?

상태 관리 라이브러리 중 하나로, 작은 패키지 크기와 직관적인 사용법이라는 장점을 가지고 있다.

특히 ContextAPI를 사용할 때와 달리 상태 변경 시 불필요한 리랜더링을 일으키지 않도록 제어하기 쉽다.

state가 변경될 때마다 React컴포넌트를 업데이트한다.

 

 

 

JavaScript에서 사용하기

1. Zustand 설치

# NPM
npm install zustand

# Yarn
yarn add zustand

 

 

2. store 생성하기

스토어를 생성하기 위해 create 함수를 사용한다.

스토어는 상태 변수와 해당 상태를 업데이트하는 액션(함수)으로 구성되어있다.

    ex_버튼을 선택하는 함수와 count를 증가시키는 함수, count를 리셋하는 함수 작성

import create from "zustand";

const useStore = create((set) => ({
  count: 0, //count 변수 선언
  selectedButton: null, //선택된 버튼의 string 값을 담을 변수 선언
  setSelectedButton: (button) => set({ selectedButton: button }), //버튼 값 설정 함수
  incrementCount: () => set((state) => ({ count: state.count + 1 })), //count 값 1 증가 함수
  removeCount: () => set({ count: 0 }), // count 0으로 초기화하는 함수
}));

export default useStore;

 

 

3. 상태 변수 및 액션 사용하기

액션을 store에서 가져오는 방법은 2가지로

첫번째는 내가 해당 파일에서 사용할 특정 변수명을 가지는 변수에 넣어 사용하고 ( 사용법1 )

두번째는 store에 정의한 이름 그대로 가져와 사용하는 방법이 있다. ( 사용법2 )

// FirstChild.js
import React from "react";
import useStore from "./store/store";

function FirstChild() {
  //   사용법 1 . store 액션을 특정 변수명을 가지는 변수에 넣어 사용하기
  //   const setSelectedButton = useStore((state) => state.setSelectedButton);
  //   const incrementCount = useStore((state) => state.incrementCount);
  //   const removeCount = useStore((state) => state.removeCount);

  //   사용법2 . store 액션을 store에 정의한 이름대로 가져와 사용하기
  const { setSelectedButton, incrementCount, removeCount } = useStore(
    (state) => state
  );

  const handleClick = (button) => {
    setSelectedButton(button);
  };

  return (
    <div>
      <h1>FirstChild</h1>
      <div>
        <button onClick={() => handleClick("O")}>O</button>
        <button onClick={() => handleClick("X")}>X</button>
      </div>
      <div>
        <button onClick={incrementCount}>카운트 증가</button>
        <button onClick={removeCount}>카운트 리셋</button>
      </div>
    </div>
  );
}

export default FirstChild;

 

액션과 마찬가지로 동일한 방법으로 상태 변수도 2가지 방법으로 가져올 수 있다.

// SecondChild.js
import React from "react";
import useStore from "./store/store";

function SecondChild() {
  //   사용법 1 . store 액션을 특정 변수명을 가지는 변수에 넣어 사용하기
  //   const selectedButton = useStore((state) => state.selectedButton);
  //   const count = useStore((state) => state.count);

  //   사용법2 . store 액션을 store에 정의한 이름대로 가져와 사용하기
  const { count, selectedButton } = useStore((state) => state);

  return (
    <div>
      <h1>SecondChild</h1>
      <p>카운트: {count}</p>
      <p>선택한 버튼: {selectedButton}</p>
    </div>
  );
}

export default SecondChild;

 

 

App.js

import "./App.css";
import FirstChild from "./FirstChild";
import SecondChild from "./SecondChild";
function App() {
  return (
    <div className="App">
      <FirstChild />
      <SecondChild />
    </div>
  );
}

export default App;

 

 

 

 

typescript로 사용하기

- 타입스크립트 사용 시에는 스토어에 타입 정의가 필요하다.

- 1과 3번은 일치하고 2번 store 코드만 달라진다.

import create from "zustand";

//타입 선언하기
interface Store {
  selectedButton: string | null;
  count: number;
  setSelectedButton: (button: string) => void;
  incrementCount: () => void;
  removeCount: () => void;
}

// 위에서 선언한 타입 사용 → 동일한 이름을 사용해야한다.
const useStore = create<Store>((set) => ({
  selectedButton: null,
  count: 0,
  setSelectedButton: (button) => set({ selectedButton: button }), //버튼 값 설정 함수
  incrementCount: () => set((state) => ({ count: state.count + 1 })), //count 값 1 증가 함수
  removeCount: () => set({ count: 0 }), // count 0으로 초기화하는 함수
}));

export default useStore;

 

 

 

 

[참조]

https://velog.io/@mjieun/React-Zustand-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0-JavaScriptTypeScript