[React] Recoil로 상태관리하기_atom, selector

·2024년 1월 3일
0

React

목록 보기
7/7
post-thumbnail

react로 개발을 하다보면, 점점 상태관리를 하는 코드가 늘어나기 마련이다.

특히 useState를 난무하는 경우가 발생하며, react의 특성 중 하나인 ‘단방향 데이터 흐름’으로 인해 useState로 상태가 변경된 값을 props를 특정 컴포넌트로 계속 전달 → 전달 → 전달하는 방식이 된다.

즉, 복잡한 상태 관리를 위해 여러 개의 useState를 사용해야 하기 대문에 상태가 복잡해지면 코드가 길어지면서, 컴포넌트 계층 구조가 깊어질수록 상태 전달이 번거롭다는 단점이 발생한다.

나는 이러한 상태관리의 복잡성과 번거로움에 지쳐 이를 해결하고자 Recoil 사용을 도입하였다.


Recoil

Recoil 장점:

  • 비동기 처리를 용이하게 지원하여 비동기 데이터 흐름 관리 가능
  • 액세스 가능한 상태와 상태 간의 의존성 추적을 제공하여 업데이트를 자동으로 처리 가능
  • useState 와 유사하게 생겼으며 [get, set] 기능 또한 동일하여 쉽게 접근할 수 있음
// useState
const [id, setId] = useState(0);

// recoil
const [count, setCount] = useRecoilState(countState);
  • Recoil을 사용하기 위해서는 부모 컴포넌트에 <RecoilRoot> 를 사용해야함 - 보통 전역으로 사용하므로 루트 컴포넌트에 넣는게 좋음
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')
);

✔️Recoil의 atom

Recoil의 경우, 공식 문서에서 예시 코드를 잘 보여주고 있다.

Atoms | Recoil

✏️Atom이란?

쉽게 말해 react의 단방향 데이터 흐름 특성으로 인해 생기는 불편함을 해소시켜준다.
useState를 사용하는 경우, 상태 전달이 번거로웠지만, atom을 이용하여 해당 상태 구조를 정의해주기만 하면, 그 상태를 어느 컴포넌트에서도 쉽게 접근할 수 있다.

  • 예시 코드
    • key : atom을 식별하는데 필요한 고유한 문자열
    • default : 초기값
export const todoListState = atom({
  key: 'TodoList',
  default: [],
});
  • useState 와 비교
// useState
const [id, setId] = useState(0);

// atom으로 상태 구조 
export const idState = atom({
  key: 'idStateKey',
  default: 0,
});

//recoil
const [id, setId] = useRecoilState(idState);


✔️Recoil의 Selector

Selectors | Recoil

✏️Selector이란?

  • atom에서 불가능한 비동기 처리와 복잡한 로직 구현 가능
  • 기존에 선언한 atom 을 전/후 처리하여 새로운 값을 반환하거나 기존 atom 값을 수정하는 역할 수행

Selector: derived state(파생된 상태)를 나타내는데 사용
파생된 상태란 기본 상태를 입력으로 받아 변환된 값을 출력하는 상태

  • 예시 코드
    • key : 고유한 문자열
    • get : 다른 atom이나 selector의 상태를 읽는 데 사용
      • 다른 atom/selector의 값을 가져와 현재 selector에서 사용할 수 있음
    • set : atom의 상태를 설정하거나 업데이트하는 데 사용
      • 주로 비동기 작업을 수행한 후 atom의 상태를 업데이트할 때 사용
      • 2개의 매개변수: 첫번째- recoil의 상태(textState), 두번째 - 어떤값으로 바뀔지, 즉 새로운 값
// 사용자의 입력을 저장하는 atom
const textState = atom({
  key: 'textState', // 고유한 키
  default: '', // 기본값
});

// 텍스트의 길이를 계산하는 selector
// set 함수: 입력된 텍스트를 대문자로 변환하여 atom을 업데이트
const textLengthSelector = selector({
  key: 'textLengthSelector',
  get: ({get}) => {
    const text = get(textState);
    return text.length;
  },
  set: ({set}, newValue) => {
    // 예를 들어, 텍스트를 대문자로 변경
    const upperCaseText = newValue.toUpperCase();
    set(textState, upperCaseText);
  }
});
  • 컴포넌트에서 이용
// import문은 생략

function TextComponent() {
  const [text, setText] = useRecoilState(textState);
  const textLength = useRecoilValue(textLengthSelector);

  return (
    <div>
      <input type="text" value={text} onChange={(e) => setText(e.target.value)} />
      <p>Text Length: {textLength}</p>
    </div>
  );
}

0개의 댓글