[Recoil] React의 새로운 상태관리 라이브러리

HyeonE·2023년 3월 25일
0

Recoil

목록 보기
1/2
post-thumbnail

😶‍🌫️ Recoil ?

리액트에는 많은 상태관리 라이브러리가 있다. 대표적으로 Redux, Modx가 있다. 하지만 이것들은 'React' 만을 위한 라이브러리가 아니라 다른 환경에서도 사용할 수 있다.

하지만 Recoil은 다른 라이브러리들과 달리 React 전용 상태관리 라이브러이며 hooks문법에 최적화 되어있다. hooks문법에 익숙한 사용자라면 빠른 시간 내에 배울 수 있다.

💻 리액트의 상태관리

리액트의 상태들을 관리할 수 있는 방법은 많다. 리액트 자체에 내장된 Context API를 사용하는 방법도 있고 다른 라이브러리(Redux, Mobx 등)을 사용하는 방법도 있다.

💡 설치

create-react-app recoil_todolist --template typescript

npm install recoil

RecoilRoot

Recoil을 사용하려면 부모 컴포넌트에 RecoilRoot가 존재해야 한다. Redux의 Provider 같은 개념으로 루트 컴포넌트에 구성하는 것이 제일 좋은 방법이다.

import React from 'react';
import { RecoilRoot } from 'recoil';

import TodoForm from './TodoForm';
import TodoList from './TodoList';

const App = () => {
  return (
    <RecoilRoot>
      <TodoForm />
      <TodoList />
    </RecoilRoot>
  );
};

export default App;

Atom

atom은 Recoil에서 사용하는 상태를 정의한다. atom은 key(문자열)와 default(기본값)으로 구성되어 있으며 atom의 값을 사용하는 요소들은 atom에 내재적으로 등록되므로 상태가 업데이트 될 때마다 atom에 등록된 모든 구성 요소가 다시 렌더링되게 된다.

import { atom } from 'recoil';

export interface Todo {
  id: number;
  content: string;
}

export const todoStore = atom<Todo[]>({
  key: 'todo',
  default: [],
});

Todo List 만들기

Todo List에 나타낼 Item이다. todo의 상태값을 변경하기 위해 useSetRecoilState라는 메서드를 사용했다. useSetRecoilState는 리액트 Hooks의 useState를 사용해 생성하는 setValue처럼 상태를 변경할 때 사용하는 메서드이다.

///src/component/TodoItem.tsx

import React from 'react';
import { useSetRecoilState } from 'recoil';

import { Todo, todoStore } from '../store/todo';

interface Props {
  data: Todo;
}

const TodoItem = ({ data }: Props) => {
  const setTodo = useSetRecoilState(todoStore);

  const removeItem = () => {
    setTodo((todo) => {
      const newTodo = [...todo];
      const index = todo.findIndex((v) => v.id === data.id);
      if (index !== -1) {
        newTodo.splice(index, 1);
      }
      return newTodo;
    });
  };

  return (
    <div>
      <input type="checkbox" />
      <span>{data.content}</span>
      <span onClick={removeItem}></span>
    </div>
  );
};

export default TodoItem;

Todo List에서는 아까 생성해놓은 상태를 useRecoilValue를 사용해 가져왔다. 지금 이 방식처럼 value와 setValue를 따로따로 가져올 수도 있지만 Hooks문법처럼 한번에 가져오는 방식도 있다. useRecoilState라는 메서드를 사용하게 되면 [value, setValue] = useRecoilState(todoState)의 형식으로 편리하게 가져올 수 있다.

// src/component/TodoList.tsx
import React from 'react';
import { useRecoilValue } from 'recoil';

import { todoStore } from '../store/todo';
import TodoItem from './TodoItem';

const TodoList = () => {
  const todo = useRecoilValue(todoStore);

  return (
    <section>
      {todo.map((v) => (
        <TodoItem data={v} key={`todoData_${v.id}`} />
      ))}
    </section>
  );
};

export default TodoList;

이제 todo 상태값에 데이터를 추가할 폼을 작성했다. 여기서도 동일하게 useSetRecoilState를 사용해 데이터를 추가했다.

// src/component/TodoForm.tsx

import React, { useState } from 'react';
import { useSetRecoilState } from 'recoil';

import { todoStore } from '../store/todo';

const TodoForm = () => {
  const setTodo = useSetRecoilState(todoStore);
  const [content, setContent] = useState('');

  const onSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setTodo((todo) => {
      const id = todo.length ? todo[todo.length - 1].id + 1 : 0;
      return [...todo, { id, content }];
    });
  };

  const onChangeContent = (e: React.ChangeEvent<HTMLInputElement>) => {
    setContent(e.target.value);
  };

  return (
    <form onSubmit={onSubmit}>
      <input type="text" onChange={onChangeContent} value={content} placeholder="내용" />
      <button type="submit">입력</button>
    </form>
  );
};

export default TodoForm;

📌 결론

Recoil을 사용해본 결과, 굉장히 편하고 만족도가 높았다. 또한 기존의 React 문법과 비슷한 부분이 많아 쉽게 배울 수 있는 상태관리 라이브러기가 생겼다는 점이 좋았다. (Redux를 열심히 공부하고 있지만 정말 어려웠다... 그에 비해 Recoil은 배우기 엄청 쉬웠다) 프로젝트에서 한번 실전 적용을 해보고 비동기처리에 대해서도 더 공부해볼 예정이다. Recoil에서는 Selector 메서드를 제공해주는데 이 부분 또한 열심히 공부해봐야겠다.

**본 포스트는 다음 문서를 참고해 작성했습니다.
https://recoiljs.org/
https://medium.com/swlh/recoil-another-react-state-management-library-97fc979a8d2b
https://chanyeong.com/blog/post/10

profile
프론트엔드 개발자가 되고싶은 대학생

0개의 댓글