React.js

React 상태 관리 라이브러리

★개발일기★ 2022. 12. 2. 11:06
반응형

프론트엔드 관점에서 상태 관리는 매우 중요하고 필수적이다.
리액트는 기본적으로 state, props 로 상태를 관리한다.
리액트의 데이터 흐름은 기본적으로 부모 -> 자식 이라는 흐름을 가지는데, 자식에서 부모의 상태를 바꾸려면 props 를 넘겨줘야한다.
이를 반복하다보면 props depth가 증가해 불필요한 리렌더링이 일어나 비효율적이다.
즉 상태관리 라이브러리를 사용하자!


Redux

* Redux는 store 에 모든 상태를 저장한다. store는 오직 하나만 가질 수 있으며, 외부요소이고 리액트 내부에 접근할 수 없다.
이로써 생기는 강점은 하나의 객체 트리를 가지므로 디버깅이 용이하다.

* store 내부 상태는 action 을 통해서만 변경이 가능하다.
모든 상태(state) 들이 하나의 store 에만 집중되어 있고, 단방향성으로 이루어지기 때문에 예측 가능한 결과가 나타난다.

* reducer는 순수함수이므로 상태를 변경하는 것이 아니라, 새로운 상태를 리턴한다.

* redux의 비동기 문제인 side effect 를 관리하기 위해서는 saga 와 같은 것을 추가로 사용하자.

Recoil

* redux 의 전역 상태관리가 과연 좋을까? 에 해당하는 부분에서 나온 라이브러리 인것 같다.
지역 상태로서, get set 인터페이스로 상태를 공유한다.

* atom 과 selector 로 이루어져 있다.
* atom의 상태변화는 순수함수를 통해 이루어지는데 이를 selector 라고 한다.

* atom의 값을 변경하는 것은 atom을 구독하는 모든 컴포넌트의 렌더링이 진행된다. ( 고유 키값, 기본값 제공 해야한다 )

* selector는 비동기처리를 제공하기 때문에, 비동기 데이터를 다루기 좋다.
* selector는 redux의 reselect 와 같은 get 함수가 필요하다.
- 예시는 다음과 같다.

const foodState = atom({
  key: 'foodState',
  default: [{
    name: 'banana',
    type: 'fruit'
  }, {
    name: 'cola',
    type: 'drink'
  }],
});

const foodFilterState = atom({
 key: 'foodFilterState',
 default: 'fruit',
});

const filteredfoodState = selector({
 key: 'foodListState',
 get: ({get}) => {
   const filter = get(foodFilterState);
   const foods = get(foodState);
   return foods.filter(f => f.type === filter);
 }
});

const Animals = () => {
  const foods = useRecoilValue(filteredfoodState);
  return foods.map(f => (
       <div>{ f.name }, { f.type }</div> )
  );
}

 

* 전역 상태로 관리하게되면 유지보수 성능이슈 보안 등 신경 써야 할 부분이 생기고, 지역 변수로 관리하게 되면 단순한 구조에서는 특이점이 없겠지만 컴포넌트가 복잡해질 수록 코드가 빙빙 꼬이는 느낌을 받을 것이다.

* 무엇을 선택하여 어떻게 관리하는 개발자의 몫이다.

반응형