Redux 와 Recoil 비교

Hyun·2022년 7월 19일
7

Redux

여러 컴포넌트에 사용되는 state를 분리 통합하여 관리할 수 있게 하고 애플리케이션의 안정성을 높일 수 있는 라이브러리

1. Action

Action은 state를 바꾸는 방식 | 액션객체를 가지고있고, 반드시 type필드가 있어야한다.

2. Dispatch

Action을 발생시키는것 | action 객체를 파라미터로 받는다.

3. Reducer

변화를 일으키는 함수 | Action의 결과로 state를 어떤식으로 바꿀지 구체적으로 정의하는 부분
Reducer가 현재상태와 전달받은 action객체를 파라미터로 받아서 새로운 상태로 반환해준다
파라미터 외의 값을 의존하면안되고, 이전상태는 건드리지 않은 상태로 새로운 상태객체를 만들어 반환하는 순수함수여야한다.

4. Store

프로젝트에 리덕스를 적용하기 위해 필요한 것으로 프로젝트에는 단 한개의 Store만 가지며 상태의 중앙저장소라고 할수있다.
Store안에는 Reducer와 내장함수 등이 포함되어있다 | dispatch와 subscribe 등도 스토어의 내장함수이다.
상태를 읽을때는 getState(), 상태를 바꿀 때는 dispatch()를 호출한다.

Redux의 특징

  • 상태를 전역적으로 관리하기에 어느컴포넌트에 상태를 둬야할지 고민안해도됨
  • 단방향 데이터흐름
  • 상태관리에서 불변성유지가 매우 중요 | 상태를 읽기전용으로 취급 (Immutable.js와 같은 라이브러리가 쓰이기도 한다)
  • flux아키텍처를 따른다. (dispatch관리를 위해 redux-thunk나 redux-saga와 같은 미들웨어가 필수이다)
  • 여러 라이브러리를 함께 사용하는 경우가 있기 때문에 러닝커브가 높은 편이다
  • 액션하나를 추가하는데 작성이 필요한 부분이 많고, 컴포넌트와 스토어를 연결하는 필수적인 부분들이 있어 코드량이 많아질 수 있다.

Recoil

context API 기반으로 구현된 함수형 컴포넌트에서만 사용 가능한 페이스북에서 만든 라이브러이이다.
호환성이나 단순함을 위해선 React에 내장된 상태 관리 기능을 사용하는게 가장 바람직하다.
예를들을 Hooks나 Context API를 사용하여 상태 관리를 할 수 있는데, 그런 경우에 여러가지 한계가 존재한다.

  • 컴포넌트 상태를 공통된 상위컴포넌트까지 끌어올려 공유할 수 있지만, 이 과정에서 거대한 트리가 리렌더링이 되기도 한다.
  • Context는 단일 값만 저장가능하고, 자체 Consumer를 가지는 여러 값들의 집합을 담는 것은 불가하다
  • 위 특성으로 인해 state가 존재하는 곳부터 state가 사용되는 곳 까지 코드분할이 어렵게 된다.
    이러한 상황에서 Recoil은 React스러움을 유지하며 개선하는 방식의 라이브러리이다.
    Recoil은 방향그래프를 정의하고 리액트 트리에 붙이는데, 이 그래프의 뿌리(atom)으로부터 순수함수(selector)를 거쳐 컴포넌트로 흐른다.
  • 공유되는 상태도 리액트의 로컬상태처럼 간단하게 get/set인터페이스가 가능하도록 API가 제공된다
  • 동시성모드(Concurrent Mode)등 여러 React기능들과 호환가능하다.
  • 상태정의는 증분 및 분산되어 code splitting이 가능하다.

1. Atoms

Recoil에서 상태의 단위를 의미함 | 업데이트, 구독이 가능
atom이 업데이트되면 각각의 구독된 컴포넌트는 새로운 값을 반영해서 리렌더링된다.
Atoms는 리액트의 로컬state대신 사용할 수 있다.
동일한 atom이 여러 컴포넌트에서 사용되는 경우 모든 컴포넌트는 상태를 공유한다.
Atoms에는 고유한 키가 필요하고, 이 키는 전역적으로 고유해야 한다. | React state처럼 디폴트값도 가진다.
컴포넌트에서 atom을 읽고 쓸 때는 useRecoilState라는 훅을 사용해야한다. 이건 리액트의 useState와 비슷하나, 상태가 컴포넌트간에 공유될 수 있다는 점에서 차이가 있다. 아래 두 컴포넌트의 state는 공유된다.

2. Selector

Selector는 atoms나 다른 selectors를 입력으로 받는 순수 함수(pure function) 이다. 상위 atoms이나 selectors가 업데이트 될 경우 하위 selectors도 재 실행된다. 컴포넌트는 atom 뿐만 아니라 selectors를 구독할 수 있고, 구독하고 있는 selectors가 변경되면 구독한 컴포넌트도 리렌더링된다. Selectors는 상태를 기반으로 데이터를 계산하고 최소한의 상태 집합만 atoms에 저장하고, 파생 데이터는 selector에서 계산하면서 불필요한 상태를 만들어내지 않는다. 컴포넌트 관점에서 atoms와 selectors는 동일한 인터페이스이므로 대체 가능하다.
여기서 get속성은 계산될 함수를 의미하고 전달되는 get인자를 통해 atoms와 다른 selectors에 접근 가능하다. 여기서 접근하면 자동으로 종속 관계가 생성되어 참조했던 atoms나 selectors가 업데이트되면 이 함수도 재실행된다.
Selectors는 useRecoilValue()를 통해 조회 가능하다. useRecoilState와는 다르게 writable 하지 않고, 반환 값의 조회만 가능하다. 필요하다면 writable한 selector 작성도 가능하다.

Recoil의 특징

  1. 비동기 처리를 기반으로 작성되어 동시성 모드를 제공하기 때문에, Redux와 같이 다른 비동기 처리 라이브러리에 의존할 필요가 없다.
  • Concurrent Mode : 흐름이 여러 개가 존재하는 경우이다. 리액트에서 렌더링의 동작 우선순위를 정하여 적절한 때에 렌더링해준다.
  1. atom -> selector를 거쳐 컴포넌트로 전달되는 하나의 data-flow를 가지고 있어, 복잡하지 않은 상태 구조
  2. atom과 selector만 알고도 어느정도 구현이 가능하기 때문에 러닝커브가 비교적 낮다고 할 수 있다.
  3. store와 같은 외부 요인이 아닌 React 내부의 상태를 활용하고 context API를 통해 구현되어있기 때문에 더 리액트에 가까운 라이브러리라고 할 수 있다.
profile
FrontEnd Developer (with 구글신)

0개의 댓글