Front-End/React

[React] Zustand란? 사용하는 이유! (상태 관리 라이브러리, 사용 방법 예시)

현기 2024. 3. 14. 19:10

 

Zustand는 독일어로 '상태'라는 뜻으로

React 생태계에서 사용하는 상태 관리 라이브러리입니다.

 

현재 Redux가 압도적으로 많이 사용되고 있지만,

문법이 더러운 편이라 학습에 시간이 필요합니다.

 

Post Redux로서 사용자가 빠르게 늘고 있는

힙한 곰돌이 친구 Zustand에 대해서 알아봅시다. 😎

 


📝  사용하는 이유

 

⦁ React에서 데이터는 단방향

https://dev.to/stuxnat/final-react-project-2poi

 

기본적으로 React의 데이터 흐름은 State & Props를 사용해 단방향으로 이루어져야 한다는 원칙이 있습니다.

 

이러한 데이터 흐름은 단순하고 예측 가능하며, 컴포넌트 간의 관계를 명확히 정의하기 때문에

유지 보수성을 향상시킵니다.

 

⦁ 음.. 컴포넌트가 너무 많으면?

코딩애플 선생님 https://www.youtube.com/watch?v=3MB8DBXzEos

 

하지만 데이터를 전달하는 과정에서 거쳐야 하는 컴포넌트가 너무 많은 상황이라면 어떨까요?

1. 최상위 부모 컴포넌트에서 상태나 데이터를 가지고 있습니다.

2. 중간에 위치한 하위 컴포넌트가 해당 데이터에 접근할 필요가 있습니다.

3. 그러나 중간에 있는 다른 컴포넌트들은 해당 데이터에 접근할 필요가 없지만, 데이터를 다시 자식 컴포넌트로 전달해야 합니다.

4. 결과적으로 데이터는 여러 컴포넌트를 통과하여 목적지에 도달합니다.
이 과정을 "prop drilling"이라고 합니다.

 

❗️결과적으로 유지보수가 어렵게 되어 개발자가 피곤할 뿐만 아니라, 성능이 저하될 우려 또한 존재합니다. 

 

이렇듯이 상태는 여러 페이지, 프로덕트 전반에 걸쳐 공통으로 사용하는 경우가 있기 때문에

상태 관리 라이브러리가 등장하게 되었습니다.

 


📝 라이브러리 통계

 

⦁ npm trends 다운로드 순위

 

React의 상태 관리 라이브러리 다운로드 수 통계입니다.

 

  Zustand는 최근 1년 동안 무려 250만 다운로드 수를 기록했습니다.

  완전 힙하죠?

 


 

https://yozm.wishket.com/magazine/detail/2233/

 

리액트 상태 관리 라이브러리, 어떤 것을 써야 할까? | 요즘IT

웹 프론트엔드 개발자라면 한 번쯤 상태 관리 라이브러리에 대해 들어봤을 것이다. 이미 쓰고 있는 라이브러리를 유지하는 것도 좋지만, 현재 어떤 도구들이 나오고 있는지 꾸준히 관심을 가지

yozm.wishket.com

 현재 널리 사용되는 선택지로는 Redux, Context API, Zustand, Recoil 등이 존재합니다.

 

각 라이브러리의 특성을 자세히 알고 싶다면 요즘IT의 데브오웬님 칼럼을 추천드립니다.

 

 


📝 사용방법

공식문서 링크

https://github.com/pmndrs/zustand

항상 시작은 공식문서 정독부터 !

 

 

 공식문서를 보시면 아시겠지만 사용방법이 굉장히 간결하고 쉽습니다. 어렵지 않게 바로 프로젝트에 적용하실 수 있을겁니다.

 

그냥 공식 문서 샘플 코드를 올리기보다,  제가 회사에서 코인 데이터를 전역적으로 관리하기 위해

도입한 Zustand 코드의 일부분을 예시로 남겨놓겠습니다. 😀

 

⦁ 디렉터리 구조

src/
|-- store/
|   |-- useCoinStore.js
|   |-- useUserStore.js
|
|-- components/
|   |-- ... //뭔가 있겠죠

 

✔  전역적으로 저장하고 싶은 데이터의 use ... Store 파일을 생성해줍니다. (훅 네이밍 국룰)

 

⦁ Store 코드

// useCoinStore.js

import {create} from 'zustand';
import {favoriteCoinAPI} from '../api/favoriteCoin';

const useCoinStore = create(set => ({
  coinList: [], //코인 정보 리스트
  favoriteCoinList: [],
  isLoadingFavoriteCoinList: false, //로딩 상태

  setCoinList: coinList => set({coinList}),
  clearCoinList: () => set({coinList: []}),

  setFavoriteCoinList: favoriteCoinList => set({favoriteCoinList}),
  clearFavoriteCoinList: () => set({favoriteCoinList: []}),
  
  /* 관심코인 리스트 가져오기 메서드 */
  getFavoriteCoinList: memberId => {
    set({isLoadingFavoriteCoinList: true}); //이런 식으로 전역 로딩도 설정 가능해요
    favoriteCoinAPI
      .getFavoriteCoinList(memberId)
      .then(result => {
        set({favoriteCoinList: result.data}); //데이터 형식은 return값에 따라 변경
      })
      .catch(e => {
        console.error('Get Favorite Coin List Error:', e);
      })
      .finally(() => {
        set({isLoadingFavoriteCoinList: false}); //로딩 꺼주시고
      });
  },
}));

export default useCoinStore;

 

✔  그냥 State인데 Zustand 문법이 조금 섞였다고 이해하면 편합니다.

 데이터뿐만이 아니라 전역적으로 사용하는 메서드와 로딩상태 등도 저장할 수 있습니다.

 

Reatc에서는 컴포넌트 수준에서 상태(State)가 업데이트 되면 해당 컴포넌트를 다시 렌더링 합니다.
Zustand는 내부적으로 React의 Context API를 사용하여 상태를 전역으로 공유합니다.
따라서 Zustand의 State도 set함수를 통해 값이 업데이트 된다면 컴포넌트가 다시 렌더링 됩니다. 😀

 

⦁ 컴포넌트에서 사용할 때 코드

// 이해를 돕기 위한 샘플코드입니다.
import useCoinStore from './src/store/useCoinStore';

const App = () => {
  const {coinList, setCoinList, getFavoriteCoinList} = useCoinStore(); // Zustand Sore에서 필요한 것 가져오기 !
  
  const getData = () => {
  	... // api request
    setCoinList( data )
  }
  
  ...
  
  return (
      <div>
           {coinList} // state 쓰듯이 쓰면 됩니다!
      </div>
 );
};

 


 

 


참고 문헌 : 

https://github.com/pmndrs/zustand

https://yozm.wishket.com/magazine/detail/2233/

https://www.youtube.com/watch?v=nkXIpGjVxWU

https://yozm.wishket.com/magazine/detail/2233/