[React] Recoil

kimgyuha·2023년 5월 31일
4

React

목록 보기
2/2
post-thumbnail

Recoil 공부하게 된 이유
다른 학교 소프트웨어마이스터고등학교 학생들하고 프로젝트를 진행하기로 했다. 사실 이미 개발이 조금 시작된 상태에서 내가 합류하게 되어서 기술 스택을 구경하던 도중에 Recoil이 있었다.

Recoil이 무엇인지만 알고 있었던 나는... 심각 공부를 시작하게 되었다!

Recoil이란?

Recoil : React 전역 상태 관리 라이브러리

2020년 5월 Facebook에서 출시하였습니다. React 전용으로 출시되어 React에 최적화되어있습니다.

다른 것들은 없음?

React 상태 관리 방법중에 내장 함수인 Context API(설명)도 있지만, 하위의 모든 component들이 속성이 변경될 때마다 다시 렌더링 되는 문제가 있다. 하지만 성능이 문제임
MobX는 구현이 용이하지만, 테스트나 유지보수 측면에서 문제 나중에 공부...ㅎㅎ

Redux

Flux 패턴을 사용하는 안정적으로 상태 관리가 가능하지만, Recoil을 사용하는 이유는!

  • React 전용 라이블러리 X
  • Boiler Plate 초기 세팅 -> 비효율적, 러닝커브 높음
  • 비동기 데이터 사용할려면 추가적인 라이브러리 필요

👉 Recoil 쓰자!!

장점

페이스북 리액트 코리아 그룹의 한 포스트 내용을 가지고 왔습니다!

  • 공유 상태에도 React 로컬 상태처럼 간단한 get/set 인터페이스로 사용할 수 있도록 boilerplate-free API를 제공
  • 동시성 모드를 비롯한 다른 새로운 React의 기능들과의 호환이 가능
  • 상태 정의는 증분 및 분산되므로 코드 분할이 가능
  • 상태를 사용하는 컴포넌트를 수정하지 않고 파생된 데이터는 동기식 비동기식간에 이동할 수 있음
  • 역호환성 방식으로 전체 애플리케이션 상태를 유지하는 것은 쉬우므로, 유지된 상태는 애플리케이션 변경에도 살아남을 수 있음

Recoil 주요 개념

RecoilRoot

recoil을 사용하기 위해는 <RecoilRoot>로 감싸주어야 한다

import {RecoilRoot} from 'recoil'; // import

function App() {
  return (
    <RecoilRoot> {/* <RecoilRoot> 로 감싸기*/}
      <컴포넌트/>
    </RecoilRoot>
  );
}

export default App;

Atom

recoil에서 상태를 정의하는 방법으로 컴포넌트끼리 공유 가능한 가장 작은 단위의 state를 의미한다

import { atom } from "recoil"; // import

const todoListState = atom({
	key: 'todoListState', // unique ID (다른 atoms/selectors을 구별하기 위해)
	default: [], // default value
})

key
프로젝트 전체에서 고유한 문자 값을 가져야 함

default
atom 기본값을 설정해줌

Selector

atom에서는 불가능한 비동기 처리와 같은 복잡한 로직을 구현 가능하다
atom값을 복제해서 복제된 값을 변환시켜서 사용한다고 이해하면 된다.

  • ex) 필터링 된 todolist : 전체 todolist에서 일부 기준에 따라 필터링 된 새 리스트가 생성되어 파생됨.
  • ex) todolist 통계 : 전체 todolist에서 목록의 총 항목 수, 완료된 항목 수 같은 리스트의 유용한 속성들을 계산한여 파생됨.
// src/atom/countState
import { atom } from "recoil"; // recoil import

export default atom({
    key: 'countState',
    default: 0,
});
// src/...어쩌구저쩌구
import { DefaultValue, selector } from "recoil"; // recoil import
import countState from "../atom/countState"; // 위에서 선언한 countState atom값을 import

export default selector({
    key: "countSelector", 
    get: ({get}): number => {
        const count = get(countState); // countState 불러옴
        return count + 1; // countState 값이 바뀔때마다 1더해서 return
    },
    set: ({set}, newCount)=>{
        return set(countState, newCount + 10) // atom값을 바꿔줌
    }
})

key
atom의 key와 동일 ( 프로젝트 전체에서 고유한 문자 값을 가져야 함)

get
파생된 상태를 반환하는 곳으로 countState가 바뀔 때마다 새로운 값을 return 됨
get()을 여러번 사용 가능하며, 하나라도 값이 변하면 리렌더링 된다

set
set을 제공하면 쓰기 가능한 상태를 반환함
selector의 값을 변경하는 것이 아닌 수정 가능한 atom의 값을 바꿔줌
set()은 두가지 매개 변수 값을 받는다. -> set(atom의 값, 바꿔줄 값)


이 선 아래부터 다시 선이 나올때 까지는 get,set에 대한 이해가 잘 안되서 찾아보다가 내가 이해한 내용을 적고 있다.. 🙏
get은 선언한 selector값을 사용할 때, 실행되는 함수
set은 이 selector값이 변경될 때, 실행되는 함수


사용법

useRecoilValue, useSetRecoilState, useRecoilState,useResetRecoilState의 훅을 사용 가능하다

const [todoList, setTodoList] = useRecoilState(todoListState);
// useState와 동일 -> [원소의 상태, 원소 상태 업데이트하는 함수]
const todoList = useRecoilValue(todoListState);
// 상태 값만을 필요로하는 경우 사용
const setTodoList = useSetRecoilState(todoListState);
// 상태를 업데이트하는 함수만 필요로하는 경우 사용

atom , selector 상관없이 2개 다 이런 식으로 사용이 가능하다.

useResetRecoilState는 2개 사용이 조금 다르다.
atom은 그냥 아래 코드처럼 사용이 가능하지만,

const resetTodoList = useSetRecoilState(todoListState);

selector는 다르다. 값이 변경되면 set이 사용되기 때문에, selector set부분에서 조건 처리를 해줘야한다.

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

마무리

Recoil을 사용하자!!

atom -> 전역에서 사용 가능한 useState
selector -> atom 값에 따라 정해지는 값

맞나요...?

Redux랑 MobX같은 경우에는 다음에 공부해서 정리해보겠습니다!
읽어주셔서 감사합니다!

profile
프론트엔드가 개발자가 되고 싶은 너구리입니다

0개의 댓글