[2차 전직] Zustand

FCS_Eddy·2025년 4월 3일
1

2차전직하기

목록 보기
4/5

Zustand란?

Zustand는 React 애플리케이션에서 간단하고 효율적인 상태 관리를 제공하는 라이브러리이다. Redux보다 가볍고, 보일러플레이트코드(Boilerplate Code)가 적어 간편하게 사용할 수 있다.

Zustand의 장점

  • 가벼운 상태 관리 (Redux보다 코드가 간결)
  • 불필요한 리렌더링 방지 (shallow 비교 가능)
  • 미들웨어 지원 (persist, subscribe 등)
  • React Context보다 성능이 좋음

설치

npm install zustand

기본사용법

1) 상태 스토어 생성

// store.jsx
import { create } from 'zustand';

const useStore = create((set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 })),
  decrease: () => set((state) => ({ count: state.count - 1 })),
}));
  • useStore는 상태를 관리하는 훅입니다.

  • count는 상태 값이고, increasedecrease는 상태를 변경하는 함수입니다.

2) React컴포넌트에서 사용

// Counter.jsx
import React from 'react';
import { useStore } from './store'; // 위에서 만든 Zustand 스토어를 불러옴

const Counter = () => {
  const { count, increase, decrease } = useStore();
  //객체 구조 분해 할당

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </div>
  );
};

export default Counter;
  • useStore를 사용하여 상태 값을 가져오고 버튼 클릭 시 상태를 변경한다.

useContext API vs Zustand

- Context API는 기본적으로 상태가 변경되면 모든 하위 컴포넌트가 리렌더링 된다.

import React, { createContext, useContext, useState } from "react";

const CountContext = createContext();

const CountProvider = ({ children }) => {
  const [count, setCount] = useState(0);
  return (
    <CountContext.Provider value={{ count, setCount }}>
      {children}
    </CountContext.Provider>
  );
};

const Display = () => {
  const { count } = useContext(CountContext);
  console.log("Display 리렌더링!");
  return <h1>Count: {count}</h1>;
};

const Button = () => {
  const { setCount } = useContext(CountContext);
  console.log("Button 리렌더링!");
  return <button onClick={() => setCount((prev) => prev + 1)}>+</button>;
};

const App = () => (
  <CountProvider>
    <Display />
    <Button />
  </CountProvider>
);

export default App;

-> 문제점

  • setCount가 호출되면 CountContext.Providervalue가 변경됨 → 모든 하위 컴포넌트가 리렌더링됨
  • Display, Button 둘 다 리렌더링되지만, 사실 Buttoncount와 관련 없는데도 리렌더링됨

- Zustand는 useStore에서 특정 상태만 구독할 수 있어 불필요한 리렌더링을 방지한다.

import { create } from "zustand";

const useStore = create((set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 })),
}));

const Display = () => {
  const count = useStore((state) => state.count); // count만 구독
  console.log("Display 리렌더링!");
  return <h1>Count: {count}</h1>;
};

const Button = () => {
  const increase = useStore((state) => state.increase); // increase만 구독
  console.log("Button 리렌더링!");
  return <button onClick={increase}>+</button>;
};

const App = () => (
  <>
    <Display />
    <Button />
  </>
);

export default App;
  • Displaycount만 구독 → count가 변경될 때만 리렌더링

  • Buttonincrease만 구독 → increase 함수는 변경되지 않으므로 리렌더링 없음

  • Context API처럼 모든 하위 컴포넌트가 리렌더링되는 문제를 방지

Zustand의 추가적능 성능 최적화 기능

1) shallow비교를 사용해 불필요한 리렌더링 방지

import { shallow } from "zustand/shallow";

const { count, increase } = useStore(
  (state) => ({ count: state.count, increase: state.increase }),
  shallow
);

2) subscribe로 특정 상태 변경 감지 가능

useStore.subscribe((state) => {
  console.log("count가 변경됨:", state.count);
});

3) persist미들웨어로 상태 유지 가능

import { create } from "zustand";
import { persist } from "zustand/middleware";

const useStore = create(
  persist(
    (set) => ({
      count: 0,
      increase: () => set((state) => ({ count: state.count + 1 })),
    }),
    { name: "counter-storage" }
  )

4) Context API없이 전역상태 사용 가능

결론

-> Zustand는 Context API보다 불필요한 리렌더링을 방지하고, 코드가 더 간결하여 성능과 유지보수 측면에서 더 효율적이다.

profile
Fun,Cool,Sexy

0개의 댓글