[Recoil] Recoil 상태관리 라이브러리

2022. 11. 2. 23:34·🍞 FrontEnd/React

React의 특징 중 하나는 데이터가 단방향으로 흐른다는 점이다. 즉, 부모 component에서 자식 component로 props가 옮겨오는 식의 형태를 띄고 있다. 따라서 모든 component에서 쓰여야 하는 상태(ex 유저 정보)가 있다면 이 정보를 계속 부모에서 자식으로, 또 그 자식으로 전달해야 하는 어려움이 있다.

 

❗React의 한계
- 상태 공유를 위해 상위 요소까지 끌어올리면 거대한 트리가 재렌더될 수도...
- Context는 단일 값만을 저장할 수 있고, 자체 Consumer를 가지는 여러 값의 집합은 담을 수 없다.
- 최상단(state가 존재하는 곳)부터 트리의 잎(state가 사용되는 곳)까지의 코드 분할이 어렵다.


따라서 Redux를 통해 상태관리를 시행했지만 React에 최적화되어있지 않아서 사용에 불편함이 있었다고 한다.

 

❗먼저, Redux와 Recoil에 대해서 비교해보자면

- 액션, 리듀서, 미들웨어 등 boilerplate 코드가 많이 발생하는 Redux 와는 대조적으로 Recoil 은 boilerplate-free API 제공한다. React 의 useState 처럼 간단한 게터(get) / 세터(set) 인터페이스로 사용 가능하다.

- Redux 의 상태 구조는 트리 구조를 따르지만 Recoil 은 방향 그래프(directed graph, digraph) 를 따른다.

- Recoil 은 상태를 사용하는 컴포넌트를 수정하지 않고 파생 데이터(derived data)를 대체할 수 있다.

- 기본적으로 아톰(atom)의 데이터가 변경되면 해당 atom 을 구독하는 모든 컴포넌트들은 갱신된다. 그러나 Redux 에서는 해당 기능을 수행하기 위해 reselect 같은 3rd-party 라이브러리가 필요하다.

 

Recoil을 사용하면 atoms (공유 상태)에서 selectors (순수 함수)를 거쳐 React 컴포넌트로 내려가는 data-flow graph를 만들 수 있다. Atoms는 컴포넌트가 구독할 수 있는 상태의 단위이며 Selectors는 atoms 상태값을 동기 또는 비동기 방식을 통해 변환한다.

 

Recoil 시작해보자!


Recoil 패키지를 설치해준다.

npm install recoil

 

📌 RecoilRoot

recoil을 사용하기 위해서는 사용하고자하는 부모 컴포넌트에다 <RecoilRoot>를 사용해야 한다.
보통 전역적으로 사용하기 때문에 루트 컴포넌트에 넣는게 좋다.

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { RecoilRoot } from 'recoil';

ReactDOM.render(
  <React.StrictMode>
    <RecoilRoot>
      <App />
    </RecoilRoot>
  </React.StrictMode>,
  document.getElementById('root')
);

 

📌 Atoms

atom은 redux의 store와 같은 개념이다.

데이터 상태의 단위이며, 업데이트와 구독이 가능하다.

atom의 값이 바뀌면 구독하고있는 장소는 모두 새로운 값으로 리렌더링된다.

여러개 생성이 가능하다.

 

atom은 key와 default값을 설정해줘야 한다.

import { atom } from "recoil";

export default atom({
    key: 'countState',
    default: 0,
});

- key
atom을 식별하는데 필요한 고유한 문자열
프로젝트 전체에서 다른 atom, selector에 대해 고유해야 한다.
- default
초기값을 설정해준다.

 

atom으로 정의한 상태는 아래의 Hook을 이용하여 사용할 수 있다.

const [recoilCounter, setRecoilCounter] = useRecoilState(recoilCounterState);
const recoilCounterValue = useRecoilValue(recoilCounterState);
const setRecoilCounter = useSetRecoilState(recoilCounterState);
const resetRecoilCounter = useResetRecoilState(recoilCounterState);

 

각각의 Hook에 대해 정리하면 다음과 같다.

  • useRecoilState
    atom의 상태를 구독.
    useState Hook과 같이 배열의 첫번째 파라미터로 상태, 두번째 파라미터로 상태에 대한 setter 함수를 반환.
  • useRecoilValue
    setter 함수 없이 atom의 상태만 반환.
  • useSetRecoilState
    atom 상태 없이 setter 함수만 반환.
  • useResetRecoilState
    atom 상태를 default 상태로 reset.

 

📌Selectors

Selectors는 atom에서는 불가능한 비동기 처리와 복잡한 로직을 구현할 수 있다.
공식문서에는 아래와 같이 정의되어 있습니다.

Selector는 파생된 상태(derived state)의 일부를 나타낸다.
파생된 상태를 어떤 방법으로든 주어진 상태를 수정하는 순수 함수에 전달된 상태의 결과물로 생각할 수 있다.
순수 함수란, 함수에 동일한 인자가 주어졌을 때 항상 같은 값을 리턴하는 함수입니다. (외부의 영향은 받지 않아야 합니다.)
import { atom } from "recoil";

export default atom({
    key: 'countState',
    default: 0,
});
import { DefaultValue, selector } from "recoil";
import countState from "../atom/countState";

export default selector({
    key: "countSelector",
    get: ({get}): number => {
        const count = get(countState);
        return count + 1;
    },
    set: ({set, get}, newCount)=>{
        return set(countState, newCount + 10)
    }
})

selector는 총 세 가지 값을 가진다.


- key
atom의 key와 동일하며 프로젝트 전체에서 고유한 문자열을 가져야 한다.
- get
파생된 상태를 반환하는 곳
get(countState) 처럼 countState를 get하고 있으면 countState가 바뀔 때마다 새로운 값을 리턴해준다.
get()을 여러번 사용 가능하고 그중 하나라도 변하게 되면 리렌더링된다.

   get: ({get}): number => {
        // countState를 구독하고 있습니다.
        // countState가 바뀔 때마다 1증가 시켜서 반환합니다.
        const count = get(countState);
        return count + 1;
    },

 

- set
set 없이 get만 제공되면 selector는 read-only 한 상태이지만 set을 제공하면 쓰기 가능한 상태를 반환한다. 
set은 selector의 값을 수정하는 것이 아닌  수정 가능한 atom의 값을 바꿔준다.

    set: ({set, get}, newCount)=>{
    	// 설명을 위한 코드로,
        // 현재 count는 사용하고 있지 않습니다.
    	const count = get(countState);
        
        return set(countState, newCount + 10)
    }

set안에서의 get()은 구독하지 않으며 단순히 atom이나 selector의 값을 찾는데 사용한다.
set()은 두가지 매개변수를 받는다. 
첫 번째는 Recoil의 상태 (위 코드에서는 countState)
두 번째는 어떤 값으로 바뀔 건지 즉 새로운 값을 넣는다.
만약 전달받은 새롭운 값이 업데이트 함수나 초기화 액션이라면 DefaulValue 일 수도 있다.

 

📌 비동기 Selector

const myQuery = selector({
  key: 'MyQuery',
  get: async ({get}) => {
    return await myAsyncQuery(get(queryParamState));
  },
});

atom을 직접 사용할 때 비동기 통신을 하는게 아닌 위 코드와 같이 seletor 안에서 비동기 통신 후 값을 사용할 수 있다.

 

Recoil 시작하기 | Recoil

React 애플리케이션 생성하기

recoiljs.org

저작자표시 (새창열림)

'🍞 FrontEnd > React' 카테고리의 다른 글

[React] 리액트 프로젝트에 구글 폰트 적용하기  (0) 2022.11.18
[React] 리액트 JWT (JSON Web Token)  (0) 2022.11.08
[React] Uncaught TypeError index.js  (0) 2022.11.02
[MSW] 데이터 모킹 라이브러리 (Mock Service Worker)  (0) 2022.11.01
[Redux] React Redux 상태관리 라이브러리  (0) 2022.11.01
'🍞 FrontEnd/React' 카테고리의 다른 글
  • [React] 리액트 프로젝트에 구글 폰트 적용하기
  • [React] 리액트 JWT (JSON Web Token)
  • [React] Uncaught TypeError index.js
  • [MSW] 데이터 모킹 라이브러리 (Mock Service Worker)
박빵이
박빵이
2025년에도 갓생살기
  • 박빵이
    기억보다 기록
    박빵이
  • 전체
    오늘
    어제
    • 분류 전체보기 (337)
      • 🍞 FrontEnd (97)
        • HTML+CSS (4)
        • JavaScript (17)
        • TypeScript (4)
        • React (52)
        • Next.js (2)
        • Android (15)
      • 🍞 BackEnd (24)
        • Java (15)
        • Node.js (6)
        • Spring (1)
      • 🍞 Cloud & Infra (0)
        • AWS SAA (0)
        • Microsoft Azure (0)
      • 🍞 Algorithm (147)
        • C++ (4)
        • Baekjoon (41)
        • Programmers (97)
      • 🍞 Computer Science (18)
        • 운영체제 (1)
        • 데이터 통신 (6)
        • 네트워크 (6)
        • 데이터베이스 (1)
      • 🍞 대외활동 & 부트캠프 (42)
        • 삼성 청년 SW 아카데미 (1)
        • LG유플러스 유레카 (0)
        • 한국대학생IT경영학회 (1)
        • IT연합동아리 UMC (17)
        • 길벗 블로깅 멘토 (18)
        • IT연합동아리 피로그래밍 (3)
        • 개발 컨퍼런스 (2)
  • 블로그 메뉴

    • Admin
  • 링크

    • GitHub
  • 인기 글

  • 태그

    level2
    코틀린
    안드로이드
    알고리즘
    react
    C++
    길벗 블로깅 멘토링
    유니온파인드
    백준
    프로그래머스
    위상정렬
    Front
    map
    코딩자율학습
    umc
    JavaScript
    level1
    Android
    길벗 블로깅 멘토
    Java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
박빵이
[Recoil] Recoil 상태관리 라이브러리
상단으로

티스토리툴바