recoil 설치하기
npm install recoil
위의 명령어를 써서 최신 recoil을 설치해준다.
RecoilRoot 적용하기
recoil를 next.js 프로젝트에 적용하려면 root에 RecoilRoot를 적용해야 한다. root가 있는 곳은 layout.js를 말한다. RecoilRoot는 Recoil로 관리되는 상태의 공급자(provider) 역할을 하며, 때문에 Recoil로 관리되는 상태를 사용하는 컴포넌트는 RecoilRoot의 하위에 존재해야 한다.
위의 코드에 {children}으로 되어 있는 태그를 RecoilRoot로 감싸야 한다. 그러나, 이를 감쌀 경우 아래와 같이 오류가 난다.
‘use client’를 최상위에 작성하라는 오류이다. 그러나 이렇게 해도 오류가 난다. Layout.js의 경우 서버사이드 컴포넌트로 use client를 작성할 경우 작동하지 않는다.
이럴 경우, RecoilRoot를 별도의 클라이언트 사이드 컴포넌트로 만든다. 그리고 이를 layout.js로 가져와서 사용함으로 이를 해결해줄 수 있다.
// RecoilWrapper.js
"use client";
import { RecoilRoot } from "recoil";
export default function RecoilRootWrapper({
children,
}) {
return <RecoilRoot>{children}</RecoilRoot>;
}
// layout.js
import RecoilRootWrapper from "@/components/RecoilWrapper";
export default function RootLayout({
children,
}) {
return (
<html lang="en">
<body className={inter.className}>
<RecoilRootWrapper>{children}</RecoilRootWrapper>
</body>
</html>
);
}
위와 같이 하면 해결이 된다.
Recoil의 hook 적용하기
1.useRecoilState
import { atom, useRecoilState } from 'recoil';
// Atom 정의
const textState = atom({
key: 'textState', // 고유한 키
default: '', // 초기값
});
function TextInput() {
const [text, setText] = useRecoilState(textState);
const onChange = (event) => {
setText(event.target.value);
};
return <input type="text" value={text} onChange={onChange} />;
}
atom에서 저장된 키를 function에서 useRecoilState를 사용하여 이를 useState와 같은 형태로 저장된 상태를 읽고 쓰는 데 사용된다.
2. useRecoilValue
import { useRecoilValue } from 'recoil';
function TextDisplay() {
const text = useRecoilValue(textState);
return <div>{text}</div>;
}
Recoil의 atom 또는 selector의 값을 읽는 데 사용된다.
3. useSetRecoilState
import { useSetRecoilState } from 'recoil';
function TextUpdater() {
const setText = useSetRecoilState(textState);
const onClick = () => {
setText('Hello, Recoil!');
};
return <button onClick={onClick}>Update Text</button>;
}
상태를 변경할 수 있는 훅이다.
4. useResetRecoilState
import { useResetRecoilState } from 'recoil';
function ResetButton() {
const resetText = useResetRecoilState(textState);
return <button onClick={resetText}>Reset</button>;
}
useResetRecoilState 훅은 Recoil의 atom 상태를 초기값으로 재설정한다.
🫣 5. useRecoilValueLoadable
import { selector, useRecoilValueLoadable } from 'recoil';
// 비동기 Selector 정의
const asyncDataState = selector({
key: 'asyncDataState',
get: async () => {
const response = await fetch('https://api.example.com/data');
return response.json();
},
});
function AsyncDataComponent() {
const loadable = useRecoilValueLoadable(asyncDataState);
switch (loadable.state) {
case 'hasValue':
return <div>{loadable.contents}</div>;
case 'loading':
return <div>Loading...</div>;
case 'hasError':
return <div>Error: {loadable.contents.message}</div>;
}
}
useRecoilValueLoadable 훅은 비동기 selector의 상태를 관리하는 데 사용된다. 이 훅은 데이터의 로딩, 에러, 완료 상태를 쉽게 처리할 수 있게 해준다.
값 읽어올 때 문제 해결하기
내 경우 useRecoilValue을 사용하여 selector의 값을 읽어올려고 했다. 그런데 render의 문제가 생기면서 계속 사이트에 warning이 떴다. 그래서 해결할려고 구글링해보니, useEffect안에 useRecoilValueLoadable로 selector의 값을 가져오면 해결이 되었다. 여기서 useRecoilValueLoadable은 Recoil의 훅 중 하나로, Recoil 상태를 읽어오는 동시에 해당 상태의 로딩 상태를 알려준다.
이를 통해 비동기적으로 데이터를 가져올 때 로딩 상태를 효과적으로 다룰 수 있다. 또한, hasVaule, loading, hasError의 값을 switch 사용하여 값을 불러오거나 값을 보여주면 해당 에러가 해결되었다.
👇🏻 참고 사이트
https://velog.io/@khakisage/Next.js-Recoil-적용하기
https://velog.io/@adultlee/Recoil에-대해서-가볍게-톺아보기#recoil의-다양한-hook들