들어가며
앞서 시작하기를 통해서 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 |