recoil은 useRecoilValueLoadable이라는 함수를 제공한다. 해당 함수는 비동기 데이터를 처리할 때 처리 상태를 함께 리턴해주어서 비동기 데이터 상태에 따라 여러가지 로직을 제어할 수 있도록 해준다.
const sample = useRecoilValueLoadable(sampleState)
이처럼 사용방법은 useRecoilValue와 동일하지만, 제공하는 값에서 차이가 발생한다. useRecoilValueLoadable이 반환한 sample이라는 값은 content와 state를 key로 갖는 object를 반환한다.
{
state: "loading"|"hasValue"|"hasError",
content: Promise | value | error
}
state는 현재 로딩중인지, 성공적으로 값을 가져왔는지, 에러가 발생했는지 여부를 알려주고, content는 state가 loading이라면 Promise, hasValue라면 성공적으로 가져온 데이터가, hasError라면 에러가 담겨있다.
useRecoilValueLoadable을 사용하면 Suspense를 대체할 수 있다.
const SomeComponent = ()=>{
const loadable = useRecoilValueLoadable(sampleState)
return <div>
<div>{loadable.state === 'loading' ? "Loading..." : loadable.content}</div>
</div>
}
export default SomeComponent
뿐만 아니라 loading 상태를 직접적으로 알 수 있으므로, 화면제어 뿐만 아니라 필요에 따라 여러가지 로직까지 처리할 수 있어서 보다 활용도가 높다는 장점도 있다.
해당 데이터의 setter도 필요한 경우 useRecoilStateLoadable함수도 이용할 수 있으니, 필요에 따라 선택해 사용하면 된다.
const [sample,setSample] = useRecoilStateLoadable(sampleState)