티스토리 뷰

1. 상태 관리의 중요성

우선 상태관리가 왜 필요한지 알아야 했다.

리액트는 단반향으로 바인딩을 하는 라이브러리이기 때문에 부모 -> 자식 방향으로만 state를 props로 전달할수 있고, 자식의 props를 부모에게 전달하는 방법은 존재하지 않는다.

 

대신 자식 컴포넌트에서 부모 컴포넌트의 state를 바꿀 수 있는 방법들이 존재한다.

1. 자식에게 부모의 state를 modify 할 수 있는 setState 함수를 props로 넘겨준다.
2. React 에서 자체적으로 제공하고 있는 Context API
3. State Management Tool(redux, recoil, ...)

Parent.js

import React, { useState } from "react";
import Children from "./Children.js"

const Parent = () => {
	const [name, setName] = useState('foo');
	return(
    	<div>
        	<Children name={name} setName={setName}/>
        </div>
    );
}

export default Parent;

Children.js

import React from "react";

const Children = ({name, setName}) => {
  useEffect(()=>{
  	setName('bar');
  },[]);
	return(
    	<div>
        	MY Parent's name is {name}
        </div>
    );
}

export default Children;

다음과 같은 예시처럼, 부모 컴포넌트의 setName() 함수를 자식 컴포넌트 props로 내려보내 자식 component에서 state를 변경할 수 있다. 하지만 1번과 같은 방법은 조금만 규모가 큰 app에 대해선 상태 관리에 어려움을 겪에 된다. 자식을 내려보내는 depth가 조금만 깊어지면 1번과 같은 방법은 효율적이지 않다. 그래서 3번과 같은 State Management Tool이 나오게 된 것이다.


이건 Redux를 예시로 든 모습인데, Redux에서는 전역 객체인 store를 두고 state를 store에 전역으로 관리하여 어떤 components 에서도 state를 변경하고 조회할 수 있다.

 

React 팀은 16.3 버전에서 라이브러리를 사용하지 않아도 자체적으로 전역 상태를 관리할 수 있는 Context API 를 출시 했습니다. 그런데 React 팀에서 공식적으로 출시한 상태관리 API 가 있음에도 불구하고, 왜 많은 프로젝트에서 Redux 와 같은 상태 관리 라이브러리를 사용할까요? 그 이유는 Context API 를 사용할 때 익혀야 하는 기본적인 개념과 작성해야 하는 코드의 길이가 Redux 의 보일러 플레이트와 크게 차이나지 않기 때문입니다. 그렇기에 기존의 코드에서 벗어나 Context API 를 사용할 필요가 없는 것입니다.

 

2. Redux VS Recoil

원래 React 프로젝트의 대부분은 Controller가 여러 Model을 제어하고 있는 구조인  MVC 아키텍처 이라는 구조로 설계하고 있었다. 하지만, 프로젝트의 규모가 커지면서 상태도 많아졌기 때문에 Model과 View가 양방향으로 영향을 미치는 이 구조의 관리가 어려워졌다. 특히 규모가 큰 Facebook에서 이러한 패턴으로는 단순한 상태의 변화도 예측가능한 범위를 벗어나 관리가 힘들다고 판단해 새로운 아키텍처를 고안해 내었다.

그래서 Facebook이 고안한 Flux 아키텍처 가 많이 사용되고 있다. 그림과 같이 데이터의 흐름은 무조건 단방향으로 흐르게 된다. dispatcher에서 action을 통해 store로, store에서 view로 또 다시 view 에서 action을 통해 dispatcher로 흐르게 되는 구조이다.

이 Flux 아키텍처를 따라간 구현체가 바로 가장 인지도가 높고 많이 사용되는 Redux 상태관리 툴이다. action, reducer, selector, store를 초기 세팅하는 부분은 간단한 상태 하나를 관리하더라도 많은 코드를 소모하였고 React에 최적화 된 라이브러리가 아니었기에 사용에 불편함이 많았다. 하지만 명확한 대체재가 없었고, 가장 큰 생태계를 구성하고 있기 때문에 사용량은 제일 높았지만, 그에 비해 만족도는 Vuex에 비해서도 낮은 수준을 기록하고 있었다.

 

그리고 마침내 2020년 Facebook에서는 Recoil을 다음과 같이 표현하며 출시하게 된다.

A state management library for React
React를 위한 상태관리 라이브러리!!

 

아래는 npm trend 로 몇가지 리액트 라이브러리 다운로드 추세를 비교한 그래프이다.

사실 비교하는 게 무의미 할 정도의 격차를 살펴볼 수 있다. 라이브러리 간 격차가 왜 이렇게 두드러지게 보일까?

아마도 출시일 Recoil 은 2020년 5월에 출시된 State Management Library 이고, Redux 무려 7년 전에 개발된 라이브러리이기 때문에 세월의 차이가 있는것이 아닐까..

 

 

그럼 이제 2개 라이브러리의 특징들을 살펴보자!

💡 Redux

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

✍️ boilerplate 코드란?

최소한의 변경으로 여러곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드

 

💡 Recoil

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

  • 컴포넌트 상태를 공통된 상위 컴포넌트까지 끌어올려 공유할 수 있지만, 이 과정에서 거대한 트리가 리렌더링 되기도 한다.
  • Context는 단일 값만 저장 가능하고, 자체 Consumer를 가지는 여러 값들의 집합을 담는 것은 불가하다.
  • 위 특성으로 인해 state가 존재하는 곳 부터 state가 사용되는 곳 까지 코드 분할이 어렵게된다.

이러한 상황에서 Recoil은 React스러움을 유지하며 개선하는 방식의 라이브러리이다. Recoil은 방향 그래프를 정의하고 리액트 트리에 붙이는데, 이 그래프의 뿌리(atom)으로 부터 순수 함수(selector)를 거쳐 컴포넌트로 흐른다.

  • 공유되는 상태도 리액트의 로컬 상태처럼 간단하게 get/set 인터페이스 가능하도록 API가 제공된다.
  • 동시성 모드(Concurrent Mode)등 여러 React 기능들과 호환 가능하다.
  • 상태 정의는 증분 및 분산되어 code splitting 이 가능하다.

Recoil 특징

 

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

 

왜 Redux 대신 Recoil 을?

위에서 살펴본 대로 Redux 는 React 에서 추구하는 데이터의 흐름을 그대로 구현해 놓은 라이브러리이다. 그렇다면 상태 관리 라이브러리를 선택할 때 Redux 대신 Recoil 을 선택할 이유를 생각해보자!

 

  1. Redux의 복잡한 코드
    Redux 를 사용하고자 할 때 마주하는 가장 큰 어려움은 복잡한 코드다. Redux 를 활용하기 위해서는 action, dispatcher, reducer, store 등 구현해야 할 기본 코드 들이 큰 편이다. 이는 보일러 플레이트를 활용해서 해결할 수 있는 문제지만, 만약 여러 개발자가 공동 작업 할 때 컨벤션을 적용하지 않고 코드를 작성할 경우 자기만 알아볼 수 있는 구조의 코드를 작성하게 된다.

  2. 간단한 Recoil 의 개념
    Redux 를 이해하고 사용하려면 공부해야 할 것들이 많다. 데이터의 흐름을 추상화 하여서 익히려고 하여도 여러가지 복잡한 흐름을 이해하는 건 쉽지 않다. 이에 비해서 Recoil 에서 state 를 관리하는 방법은 굉장히 간단해 보인다.

  3. 쉽게 사용하는 비동기 로직
    Redux 에서 비동기를 활용하기 위해서는 middleware 을 활용한다. 비동기 통신을 한다면 통신의 결과가 Success 일수도 있고 Fail 일 수도 있다. 이를 구분하여 state 관리를 해야하는데, 이를 쉽게 하기 위해서 Redux 에서는 Redux-thunk 혹은 Redux-saga 같은 미들웨어를 활용한다. 하지만 Recoil 에서는 내장된 개념인 selector 을 활용해 추가적인 미들웨어의 사용 없이 쉽게 비동기 로직을 구현할 수 있다.

 

 

 

참고)

https://velog.io/@juno7803/Recoil-Recoil-200-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0

https://tech.osci.kr/2022/06/16/recoil-state-management-of-react/

https://ykss.netlify.app/react/redux_mobx_recoil/

https://tech.osci.kr/2022/06/16/recoil-state-management-of-react/

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함