이전에 연습할 때 만들었던 useAsync와 비슷한 함수가 들어있는 라이브러리이다. 프로젝트를 만들 때마다 요청 상태 관리를 위한 커스텀 Hook을 만들기 귀찮을 때 사용하면 된다. 차이점이 있다면 직접 만들었던 커스턴 Hook은 결과물을 배열로 반환했지만, 이 Hook은 객체형태로 반환한다.
우선 해당 라이브러리를 설치하자.
yarn add react-async
이전에 사용한 useAsync 대신 {useAsync}
를 사용할 것이다. getUser에서 파라미터로 사용하던 id를 객체 형태로 바꿔야한다. 또 User함수에서 useAsync
에서 state를 불러왔었는데 이것 대신에 비구조화 할당을 통해 data,error,isLoading(Loading 대신으로 바꿈) 값을 불러온다.
function User({id}) {
const {
data: user,
error,
isLoading
} = useAsync({
promiseFn: getUser,
id,
watch: id,
}); //id값이 바뀔때마다 호출할거임
if (isLoading) return <div>로딩중</div>
if (error) return <div>에러가 발생했음</div>
if (!user) return null;
return (
<div>
<h2>{user.username}</h2>
<p>
<b>Email: </b> {user.email}
</p>
</div>
);
}
실행해도 같은 화면으로 잘 실행된다.
이번엔 Users컴포넌트도 {useAsync}
를 사용해서 수정해보자. data와 error, isLoading과, reload를 가져온다.
function Users() {
const [userId, setUserId] = useState(null);
const {data:users, error, isLoading, reload} = useAsync({
promiseFn:getUsers
})
/* const[state, refetch] = useAsync(getUsers, [],true);
const {loading, data:users, error} = state; */
if(isLoading) return <div>로딩중</div>
if(error) return <div>에러 발생</div>
if(!users) return <button onClick={reload}>불러오기</button>
return (
<>
<ul>
{users.map(user => (
<li key={user.id} onClick={() => setUserId(user.id)}>
({user.name})
</li>
))}
</ul>
<button onClick={reload}>다시 불러오기</button>
{userId && <User id={userId} /> }
</>
);
}
여기 까지 수정을 진행하고 다시 실행하면, 불러오기 버튼이 나타나지 않고, 바로 데이터가 출력된다. 이전처럼 사용자가 원하는 시점에 데이터를 출력하게끔 하고 싶으면 deferFn
을 사용하면 된다. 그리고 reload옆에 run이라는 항목도 추가해서 불러오기 onClick 호출함수로 run으로 변경한다.
const {data:users, error, isLoading, reload, run} = useAsync({
deferFn:getUsers
})
if(isLoading) return <div>로딩중</div>
if(error) return <div>에러 발생</div>
if(!users) return <button onClick={run}>불러오기</button>
다시 제대로 동작한다.