Recoil

2023. 1. 19. 17:22프로그래밍/React

    목차

Recoil

React 애플리케이션을 위한 상태 관리 라이브러리
Redux 보다 초기 설정 코드 작성 부분이 최소화 됨
페이스북에서 만들어졌기 때문에 리액트와 호환성이 좋음

 

recoil 설치

npm install recoil --save

 

RecoilRoot

루트 컴포넌트를 RecoilRoot 로 감싸주면
하위 컴포넌트에서 recoil 상태 사용 가능
import { RecoilRoot } from 'recoil';

...

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <RecoilRoot>
    <App />
  </RecoilRoot>
);

 

Atom

상태의 일부를 나타냄
모든 컴포넌트에서 읽고 쓸 수 있음
atom 의 값을 읽는 컴포넌트들은 암묵적으로 atom 을 구독함
때문에 atom 에 변화가 있을 경우 구독하는 모든 컴포넌트가 리렌더링 됨
export const textState = atom({
  key: 'textState',
  default: '',
});

key: 고유한 key값, 일반적으로 atom을 생성하는 변수명으로 지정함

default: 초기값 설정

 

useRecoilState

컴포넌트가 atom을 읽고 쓸 수 있음
import { useSetRecoilState } from 'recoil';
import { textState } from '../App';

...

const TextInput = () => {
  const [text, setText] = useRecoilState(textState);
  
  const onChange = (event) => {
    setText(event.target.value);
  };
  
  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      {text}
  );
};

 

useRecoilValue

상태 값을 읽을 수 있음
const CharacterCount = () => {
  const count = useRecoilValue(charCountState);
  return <>{count}</>;
}

export default CharacterCount;

 

종류 설명
useRecoilState() useState()와 유사함
[state, setState] 튜플을 반환함
인자에 Atoms / Selector를 넣어줌
useRecoilValue() 전역 상태의 state 상태 값만을 참조하기 위해 사용함
선언된 변수에 할당하여 사용
useSetRecoilState() 전역 상태의 setter 함수만을 활용하기 위해 사용함
선언된 함수 변수에 할당하여 사용
useResetRecoilState() 전역 상태를 default 값으로 Reset 하기 위해 사용함
선언된 함수 변수에 할당하여 사용

 

Selector

atom 또는 다른 Selector 상태를 입력받아 동적인 데이터를 반환하는 순수함수
Selector가 참조하던 다른 상태가 변경될 경우 함께 업데이트되며
이때 Selector를 바라보던 컴포넌트들이 리렌더링 됨
import { selector } from 'recoil';

...

export const charCountState = selector({
  key: 'charCountState',
  get: ({get}) => {
    const text = get(textState);
    return text.length;
  },
});

key: 고유한 key값

get: Selector 순수 함수, 사용할 값을 반환하며

매개변수인 콜백 객체 내 get()메서드를 이용해 다른 atom 또는 selector를 참조 가능

 

비동기 데이터 쿼리

const currentUserIdState = atom({
  key: 'CurrentUserId',
  default: 1,
});

const currentUserNameQuery = selector({
  key: 'CurrentUserName',
  get: async ({ get }) => {
    const path = "https://jsonplaceholder.typicode.com/users";
    const response = await axios.get(`${path}${get(currentUserIdState)}`);
    return response.data.name;
  },
});

function CurrentUserInfo() {
  const userName = useRecoilValue(currentUserNameQuery);
  return <div>{userName}</div>;
}

function App() {
  return (
    <div>
      <CurrentUserInfo />
    </div>
  );
}

selector 는 기본적으로 값을 자체적으로 캐싱함

만약 입력된 적 있는 값이라면 그 값을 기억하고,

해당 값이 다시 호출되면 이전에 캐싱된 결과를 바로 보여주기 때문에

비동기 데이터를 다룰 때 유리함

(currentUserIdState 가 변경되지 않을 경우 이전 결과를 바로 보여줌)

 

React Suspense 와 함께 사용하기

<Suspense fallback={<div>Loading...</div>}>
  <CurrentUserInfo />
</Suspense>

Recoil 은 보류 중인 데이터를 다루기 위해서 React Suspense와 함께 동작하도록 디자인 되어있음

컴포넌트를 Suspense의 경계로 감싸서 아직 보류 중인 하위 항목들을 잡아내고 대체하기 위한 UI를 렌더함