본문 바로가기
매일 해내는 개발/React

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

by 해야지 2023. 3. 1.
반응형

리코일이란?

리코일(Recoil)은 React 상태 관리 라이브러리 중 하나이다.
리액트에서 상태를 관리하기 위해서는 일반적으로 상태를 컴포넌트 내부에서 관리하거나 Redux와 같은 라이브러리를 사용한다. 하지만 Redux는 보일러플레이트 코드가 많고, 컴포넌트와 액션 사이의 연결을 설정하는 작업이 번거로울 수 있다. 반면, 리코일은 상태를 단일 원천으로 중앙 집중적으로 관리하면서도 이러한 불편함을 해소한다.

리코일은 상태 값을 저장하고 업데이트하는 데 사용되는 atom과 여러 selector로 구성된다. atom은 원자적으로 업데이트 가능한 상태 값을 나타내며, selector는 atom을 기반으로 다른 값을 계산하는 데 사용된다.

리코일은 기존의 리액트 상태 관리 방법보다 더 직관적이고 간단하게 상태 값을 관리할 수 있다. 또한, 비동기 데이터를 처리하는 데도 유용하며, 상태 업데이트를 처리하는 데 필요한 보일러플레이트 코드가 없어 코드 작성 시간을 절약할 수 있다.

리코일을 사용하기 위해서는 먼저 recoil 패키지를 설치하고, RecoilRoot 컴포넌트를 이용하여 상태 값을 관리할 컴포넌트를 감싸주어야 한다. 그리고 atom과 selector를 이용하여 상태 값을 정의하고 업데이트할 수 있다.

 

리코일의 특징

1. 중앙 집중화된 상태 관리
리코일은 중앙 집중화된 상태 관리를 지원하여, 상태를 공유하고 관리하는 것이 용이하다. 이를 통해 상태가 어디서 변경되었는지 추적하고, 컴포넌트 간에 일관성 있는 데이터 흐름을 유지할 수 있다.

2. 비동기 상태 관리
리코일은 비동기 상태 관리를 지원한다. React의 useEffect 훅과 유사한 useRecoilCallback 훅을 제공하여 비동기적인 상태 업데이트를 처리할 수 있다.

3. 상태 업데이트 최적화
리코일은 상태 업데이트를 최적화하여, 컴포넌트 렌더링 성능을 개선할 수 있다. 상태 변경 시, 해당 상태를 사용하는 컴포넌트만 다시 렌더링되도록 최적화되어 있다.

4. TypeScript 지원
리코일은 TypeScript를 지원한다. 타입 안정성을 유지하면서 개발할 수 있다.

5. 개발자 경험 개선
리코일은 개발자 경험을 개선하기 위한 다양한 기능을 제공한다. 예를 들어, 개발자 도구 확장 프로그램을 사용하여 상태 변경 이력을 추적하거나, 상태 스냅샷을 생성할 수 있다.

종합적으로, 리코일은 중앙 집중화된 상태 관리와 비동기 상태 관리, 최적화된 상태 업데이트, TypeScript 지원, 개발자 경험 개선 등의 특징으로, React 애플리케이션의 상태 관리를 보다 쉽고 효율적으로 처리할 수 있도록 도와준다.

 

리덕스와 리코일의 차이

1. 상태 업데이트 방식
리코일은 React Hooks를 이용한 편리한 상태 업데이트 방식을 제공한다. React Hooks는 함수 컴포넌트에서도 상태를 관리할 수 있게 해주는 React 16.8 이후에 추가된 기능이다. 반면, 리덕스는 중앙 집중화된 스토어에서 상태를 관리하며, 상태를 변경하기 위해 액션(Action)을 발생시키고 리듀서(Reducer)를 이용하여 상태를 업데이트한다.

2. 상태 관리의 복잡성
리코일은 Redux보다 덜 복잡한 상태 관리를 제공한다. 리코일은 컴포넌트에서 필요한 상태를 사용할 수 있도록 해주기 때문에, 상태의 의존성을 명확하게 파악하기 쉽고, 상태 관리의 복잡성을 낮출 수 있다.

3. 개발자 경험
리코일은 개발자 경험이 좋다. 컴포넌트의 상태 관리와 관련된 로직을 컴포넌트 내부에서 처리하기 때문에, 상태 업데이트가 간편하고, 상태 변화에 따른 렌더링을 자동으로 처리해준다. 반면, 리덕스는 별도의 파일로 액션과 리듀서를 정의해야 하기 때문에, 초기 설정이 번거로울 수 있다.

4. 상태의 범위
리코일은 컴포넌트 단위에서 상태를 관리하기 때문에, 컴포넌트 범위에서만 유효한 상태를 관리할 수 있다. 반면, 리덕스는 전역적인 상태 관리를 제공하며, 여러 컴포넌트에서 공유하는 상태를 관리할 수 있다.

5. 유지 보수성
리코일은 상태의 의존성을 명확하게 파악할 수 있기 때문에, 유지 보수성이 높다. 반면, 리덕스는 상태의 관계를 파악하기 어렵기 때문에, 유지 보수성이 낮을 수 있다.

 

리코일을 사용하는 경우와 예시

1. 중앙 집중화된 상태 관리가 필요할 때

React 애플리케이션에서 컴포넌트 간에 상태를 공유하고 일관성 있는 데이터 흐름을 유지하려면 중앙 집중화된 상태 관리가 필요하다. 예를 들어, Todo 리스트 애플리케이션에서, 다른 컴포넌트에서도 해당 Todo 리스트의 상태를 사용하고자 할 때, 리코일을 사용하여 중앙 집중화된 상태를 관리할 수 있다.

import React from 'react';
import { useRecoilState } from 'recoil';
import { todoListState } from './store';

function TodoItem({ item }) {
  const [todoList, setTodoList] = useRecoilState(todoListState);

  const handleDelete = () => {
    const newList = todoList.filter((todo) => todo.id !== item.id);
    setTodoList(newList);
  };

  return (
    <div>
      <span>{item.text}</span>
      <button onClick={handleDelete}>X</button>
    </div>
  );
}

export default TodoItem;

위 코드에서는 todoListState를 상태로 사용하고, useRecoilState 훅을 사용하여 해당 상태를 관리하고 있다.

2. 비동기 상태 처리

React 애플리케이션에서 비동기적인 데이터 처리가 필요한 경우, 리코일을 사용하여 비동기 상태 처리를 할 수 있다. 예를 들어, Todo 리스트 애플리케이션에서 Todo 아이템을 추가할 때, 서버와 비동기적으로 통신하여 새로운 아이템을 추가할 수 있다.

import React from 'react';
import { useRecoilState, useRecoilCallback } from 'recoil';
import { todoListState, getNextId } from './store';

function AddTodo() {
  const [todoList, setTodoList] = useRecoilState(todoListState);
  const addTodo = useRecoilCallback(({ set }) => async (text) => {
    const nextId = getNextId(todoList);
    const newItem = { id: nextId, text };
    const newTodoList = [...todoList, newItem];
    set(todoListState, newTodoList);
    await fetch('/api/addTodo', { method: 'POST', body: JSON.stringify(newItem) });
  });

  const handleAdd = async () => {
    await addTodo('New Todo');
  };

  return <button onClick={handleAdd}>Add Todo</button>;
}

export default AddTodo;

위 코드에서는 useRecoilCallback 훅을 사용하여 addTodo 함수를 정의하고, 해당 함수에서 비동기적으로 상태를 업데이트하고 서버와 통신하는 작업을 수행한다.

 

리코일 사용 방법

1. 라이브러리 설치

npm install recoil

2. 상태 정의

리코일은 atom이라는 개념으로 상태를 정의한다. atom은 하나의 값이며, 컴포넌트에서 읽고 쓸 수 있다.

//atom.js
import { atom } from 'recoil';

export const counterState = atom({
  key: 'counterState',
  default: 0,
});

위 코드는 counterState라는 atom을 정의하며, default값으로 0을 갖는다.

3. 상태 사용

useRecoilState 훅을 사용하여 상태를 읽고 쓸 수 있다.

//Counter.jsx
import { useRecoilState } from 'recoil';
import { counterState } from './atoms';

function Counter() {
  const [count, setCount] = useRecoilState(counterState);

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
    </div>
  );
}

위 코드는 counterState를 사용하여 상태를 읽고 쓰는 예시이다. useRecoilState 훅은 배열을 반환하며, 첫 번째 요소는 현재 상태 값이고, 두 번째 요소는 상태를 업데이트하는 함수이다.

useState를 전역으로 사용할 수 있다고 생각하면 편하다.

이외에도 useRecoilValue, useSetRecoilState, useResetRecoilState 등 다양한 훅을 사용하여 상태를 다룰 수 있다.

 

 

Recoil, 리액트의 상태관리 라이브러리 - 오픈소스컨설팅 테크블로그

Recoil 만을 위한 글이지만, 해당 기술을 탐구하기 전에 같은 문제를 해결하기 위해 사용되고 있는 라이브러리와 비교를 하는것은 상당히 중요한 일이라고 생각합니다.Frontend 개발을 하면서 state

tech.osci.kr

 

반응형

댓글