본문 바로가기

React/실험실

[React] Recoil - 사용하기

들어가며

앞서 시작하기를 통해서 Recoil에 대해서 알아봤다.

이번에는 실제 React에서 어떤 방식으로 Recoil을 사용하는지 알아보려고 한다. 

 

환경 세팅 

npx create-react-app recoil

먼저 React 프로젝트가 필요하기 때문에 간단하게 CRA를 사용해서 환경을 만들었다. 

 

yarn add recoil

당연히 recoil 패키지가 필요하기 때문에 최신 버전을 설치했다. 

 

RecoilRoot

// App.jsx
import { RecoilRoot } from "recoil";

function App() {
  return (
    <RecoilRoot>
      <div>Recoil Study</div>
    </RecoilRoot>
  );
}

export default App;

Redux에서 Provider를 사용해서 Redux를 사용할 컴포넌트를 나타냈는데, 

Recoil도 마찬가지로 RecoilRoot을 사용해서 Recoil의 상태를 전역으로 설정한다.

 

Atom

Atom은 상태를 나타낸다고 했다. 

Atom은 어떤 컴포넌트에서나 읽고 쓸 수 있으며, Atom 값을 읽는 컴포넌트는 암묵적으로 

해당 Atom을 구독하게 된다. 

 

그래서 변화가 감지되면 구독하고 있는 모든 컴포넌트에서 리렌더링이 발생하게 된다. 

import { atom, useRecoilState } from "recoil";

const numberState = atom({
  key: "numberState",
  default: 0,
});

const Counter = () => {
  return (
    <div>
      <TextInput />
      <Echo />
    </div>
  );
};

const TextInput = () => {
  const [_, setNumber] = useRecoilState(numberState);

  const handleInputChange = (e) => {
    setNumber(e.target.value);
  };

  return (
    <div>
      <input type="number" onChange={handleInputChange} />
    </div>
  );
};

const Echo = () => {
  const [number, _] = useRecoilState(numberState);

  return <div>{number}</div>;
};

export default Counter;

Counter를 하는 컴포넌트를 한 개 만들었다. 

 

const numberState = atom({
  key: "numberState",
  default: 0,
});

atom을 사용해서 상태를 만들었는데, key는 고유한 ID값으로 다른 Atom과 같은 Key를 사용하면 안된다.

 

그리고 default에는 초기값을 설정해주면 된다.

const TextInput = () => {
  const [_, setNumber] = useRecoilState(numberState);

  const handleInputChange = (e) => {
    setNumber(e.target.value);
  };

  return (
    <div>
      <input type="number" onChange={handleInputChange} />
    </div>
  );
};

 사용하는 방식은 useState와 비슷하게 useRecoilState는 state값과 setState를 return해준다. 

여기서 setState를 담당하는 setNumber는 사용해서 input이 변하게 되면 그 값을 state에 넣었다. 

 

const Echo = () => {
  const [number, _] = useRecoilState(numberState);

  return <div>{number}</div>;
};

state를 실제 사용하는 컴포넌트이다. 

TextInput에서 onChange를 통해서 값을 변경하면 Echo에 있는 number 도 구독을 하기때문에 

리렌더링이 발생하고 값이 최신화가 된다. 

 

Selector

Selector는 상태의 변화를 나타낸다. 

import { atom, selector, useRecoilState, useRecoilValue } from "recoil";

const numberState = atom({
  key: "numberState",
  default: 0,
});

const numberPlusState = selector({
  key: "numberPlusState",
  get: ({ get }) => {
    const number = get(numberState);

    return number + 10;
  },
});

// ...

const Echo = () => {
  const [number, _] = useRecoilState(numberState);
  const plusNumber = useRecoilValue(numberPlusState);

  return (
    <div>
      <p>{number}</p>
      <p>{plusNumber}</p>
    </div>
  );
};

export default Counter;

 

const numberPlusState = selector({
  key: "numberPlusState",
  get: ({ get }) => {
    const number = get(numberState);

    return number + 10;
  },
});

numberPluseState는 get을 통해서 다른 numberState의 값을 가져와서 10을 더하고 return해주고 있다.

 

const Echo = () => {
  const [number, _] = useRecoilState(numberState);
  const plusNumber = useRecoilValue(numberPlusState);

  return (
    <div>
      <p>{number}</p>
      <p>{plusNumber}</p>
    </div>
  );
};

useRecoilValue를 사용해서 numberPlusState 값을 얻어올 수 있다.

 

정리 

간단하게 Recoil을 사용해봤는데, 정리하자면 atom은 상태를 나타내고, 

selector는 atom 혹은 다른 selector의 상태를 가져와서 주어진 상태를 수정하는

순수 함수라고 보면 될 것 같다.

 

확실하게 Redux에 비해서 사용하는 방법이 훨씬 간단한 것 같다. 

Redux였다면 Store를 만드는 것부터 시작해서 신경써야하는 부분이 많았을 텐데, Recoil을 

사용해서 간단하게 구현이 가능하다!

반응형

'React > 실험실' 카테고리의 다른 글

[React] Test Coverage  (0) 2022.11.15
[React] Recoil - Todo 만들기  (0) 2022.11.11
[React] Recoil - 시작하기  (0) 2022.11.09
[React] Context API 사용하기  (0) 2022.11.05
[React] Redux vs Context API  (0) 2022.11.04