ReactJS

React - Zustand

jjangsh 2024. 9. 25. 00:47

01. Zustand의 등장배경

(1) 상태관리의 중요성

상태관리는 모든 리액트 애플리케이션에서 매우 중요합니다. 작은 규모의 애플리케이션에서는 상태관리가 간단하지만, 애플리케이션이 커질수록 상태관리는 점점 더 복잡해집니다.

 

상태(state)는 리액트 애플리케이션에서 데이터와 UI의 현재 상태를 나타냅니다. 상태가 변경되면 UI도 업데이트되어야 합니다.

 

(2) Zustand의 필요성

기존의 상태관리 라이브러리인 Redux는 제공하는 기능과 연계된 미들웨어 등 매우 강력한 퍼포먼스를 자랑하지만, 설정과 사용법이 복잡했죠! Zustand는 상태관리 본연의 기능에 집중하여 위와 같은 복잡성을 줄이고, 보다 간단하고 직관적인 상태관리 기능을 제공합니다.

 

02. Zustand의 주요 개념

(1) Zustand의 주요 특징

  • 간결함
    • 매우 간단한 API를 제공하기 때문에, 학습 곡선이 완만해요.
    • 매우 적은 설정 코드 및 적용 코드를 이용하여 상태관리 기능을 구현할 수 있어요.
  • 성능
    • 불필요한 리렌더링을 방지하는 등, 성능 최적화가 잘 되어 있습니다.
    • Zustand는 상태가 변경될 때, 해당 상태를 사용하고 있는 컴포넌트만 리렌더링 해요.
    • 상태의 일부가 변경되었을 때 그 상태를 사용하는 컴포넌트만 업데이트되므로, 애플리케이션 전체가 리렌더링 되지 않습니다. 이를 통해 성능을 최적화하고, 리렌더링으로 인한 성능 저하를 방지할 수 있습니다.
  • React와의 통합
    • React의 훅(Hook)과 완벽하게 통합됩니다.
    • Zustand는 React의 useState, useEffect와 같은 기본 훅을 사용하는 것처럼 간편하게 사용할 수 있어요.

 

(2) 설치 및 기본 사용법

Zustand 설치

yarn add zustand

 

기본 사용법

// src > zustand > bearsStore.js

import { create } from "zustand";

const useBearsStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}));

export default useBearsStore;
// src > App.jsx

import "./App.css";
import useBearsStore from "./zustand/bearsStore";

function App() {
  const bears = useBearsStore((state) => state.bears);
  const increasePopulation = useBearsStore((state) => state.increasePopulation);
  return (
    <div>
      <h1>{bears} around here ...</h1>
      <button onClick={increasePopulation}>one up</button>
    </div>
  );
}
export default App;

 

 

03. Zustand와 Redux Toolkit 비교

(1) 설정 및 사용법 비교

Zustand: 매우 간단한 설정과 사용법을 제공해요! 우리가 이미 경험해 본 대로 상태를 정의하고 사용하는 과정이 직관적이에요.

import { create } from "zustand";

const useStore = create(set => ({
  bears: 0,
  increasePopulation: () => set(state => ({ bears: state.bears + 1 }))
}))

 

 

Redux Toolkit: 보다 구조화된 방법을 제공하지만, 설정이 다소 복잡할 수 있어요. 보일러 플레이트가 너무 많다 보니 상태 하나를 관리하고자 해도 추가/설정해야 하는 것이 상당합니다.

import { configureStore, createSlice } from '@reduxjs/toolkit'

const slice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: state => { state.value += 1 }
  }
})

const store = configureStore({ reducer: slice.reducer })

 

 

(2) 장단점 비교

  • Zustand
    • 장점: 간단하고 빠르며, 설정이 매우 쉽습니다.
    • 단점: 상태가 커지면 관리가 어려울 수 있습니다.
  • Redux Toolkit
    • 장점: 구조화된 방법을 통해 대규모 애플리케이션에서도 관리가 용이합니다.
    • 단점: 설정이 복잡하고, 학습 곡선이 가파릅니다.

 

04. 예시코드

(1) 기본 예제

(1)-1. 상태 정의

// src > zustand > todosStore.js

import { create } from "zustand";

const useTodosStore = create(set => ({
  todos: [],
  addTodo: (todo) => set(state => ({ todos: [...state.todos, todo] })),
  removeTodo: (index) => set(state => ({
    todos: state.todos.filter((_, i) => i !== index)
  }))
}))

export default useTodosStore;

 

(1)-2. 상태 사용

// src > App.jsx

import React, { useState } from "react";
import useTodosStore from "./zustand/todosStore";

function App() {
  const todos = useTodosStore((state) => state.todos);
  const addTodo = useTodosStore((state) => state.addTodo);
  const removeTodo = useTodosStore((state) => state.removeTodo);
  const [input, setInput] = useState("");

  return (
    <div>
      <h1>Todo List</h1>
      <input value={input} onChange={(e) => setInput(e.target.value)} />
      <button
        onClick={() => {
          addTodo(input);
          setInput("");
        }}
      >
        Add Todo
      </button>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>
            {todo} <button onClick={() => removeTodo(index)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

 

 

05. Zustand의 장점과 단점

(1) 장점

  • 간편한 사용: 간단한 API와 직관적인 사용법을 제공합니다.
  • 성능 최적화: 불필요한 리렌더링을 방지합니다.
  • React와의 완벽한 통합: React의 훅과 잘 통합되어 있습니다.
  • 미들웨어 지원: 로깅, 퍼시스턴스 등 다양한 미들웨어를 사용할 수 있습니다.
  • 유연성: 필요한 부분만 선택적으로 사용할 수 있습니다.
  • 커뮤니티와 자료: 예전엔 다른 대형 라이브러리에 비해 상대적으로 커뮤니티와 자료가 부족할 수 있었지만 꾸준한 인기 상승으로 많은 자료가 확보되고 있습니다.

(2) 단점

  • 상태가 커지면 관리 어려움: 상태가 많아지면 관리가 복잡해질 수 있습니다.

(3) Redux Toolkit과의 비교

  • 설정과 사용법: Zustand는 설정과 사용이 간단하며, Redux Toolkit은 더 구조화된 방법을 제공합니다.
  • 성능: 두 라이브러리 모두 성능 최적화가 잘 되어 있지만, Zustand는 불필요한 리렌더링을 방지하는 데 더 초점을 맞춥니다.
  • 유연성: Zustand는 필요한 부분만 선택적으로 사용할 수 있지만, Redux Toolkit은 보다 강력한 구조화된 방법을 제공합니다.
  • 커뮤니티와 자료: Redux Toolkit은 대형 커뮤니티와 풍부한 자료를 가지고 있으며, Zustand는 상대적으로 부족할 수 있지만 현재는 많은 인기에 힘입어 늘어나고 있습니다.