Front-End/React.js
React.js | API 연동 | react-async로 요청 상태 관리하기
개발자티포
2021. 10. 7. 17:48
728x90
반응형
react-async는 우리가 지난 섹션에서 만들었던 useAsync와 비슷한 함수가 들어있는 라이브러리다.
이름은 똑같으나 사용법이 조금 다르다.
만약 매번 프로젝트를 만들 때 마다 직접 요청 상태 관리를 위한 커스텀 Hook을 만들기 귀찮으면
이 라이브러리를 사용하면 유용할 것이다.
먼저 react-async를 설치한다.
$ npm i react-async
import { useAsync } from "react-async"
const loadCustomer = async ({ customerId }, { signal }) => {
const res = await fetch(`/api/customers/${customerId}`, { signal })
if (!res.ok) throw new Error(res)
return res.json()
}
const MyComponent = () => {
const { data, error, isLoading } = useAsync({ promiseFn: loadCustomer, customerId: 1 })
if (isLoading) return "Loading..."
if (error) return `Something went wrong: ${error.message}`
if (data)
return (
<div>
<strong>Loaded some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)
return null
}
react-async의 useAsync 를 사용 할 때 파라미터로 넣는 옵션 객체에는 호출 할 함수 promiseFn 을 넣고, 파라미터도 필드 이름과 함께 costomerId를 넣어주어야 한다.
User 컴포넌트 전환
User 컴포넌트를 react-async의 useAsync 로 전환하자
import React from 'react';
import axios from 'axios';
import { useAsync } from 'react-async';
async function getUser({ id }) {
const response = await axios.get(
`https://jsonplaceholder.typicode.com/users/${id}`
);
return response.data;
}
function User({ id }) {
const { data: user, error, isLoading } = useAsync({
promiseFn: getUser,
id,
watch: 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>
);
}
export default User;
react-async를 사용할 때에는 프로미스를 반환하는 함수의 파라미터를 객체형태로 해주어야 한다.
async function getUser({ id }) {}
그리고 watch 값에 특정 값을 넣어주면 이 값이 바뀔 때마다 promiseFn에 넣은 함수를 다시 호출한다.
Users 컴포넌트 전환
Users.js
import React, { useState } from 'react';
import axios from 'axios';
import { useAsync } from 'react-async';
import User from './User';
async function getUsers() {
const response = await axios.get(
'https://jsonplaceholder.typicode.com/users'
);
return response.data;
}
function Users() {
const [userId, setUserId] = useState(null);
const { data: users, error, isLoading, reload } = useAsync({
promiseFn: getUsers
});
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)}
style={{ cursor: 'pointer' }}
>
{user.username} ({user.name})
</li>
))}
</ul>
<button onClick={reload}>다시 불러오기</button>
{userId && <User id={userId} />}
</>
);
}
export default Users;
이전에 사용했던 skip처럼 나중에 데이터를 불러오려면 promiseFn 대신 deferFn, reload 대신 run 함수를 사용한다.
Users.js
import React, { useState } from 'react';
import axios from 'axios';
import { useAsync } from 'react-async';
import User from './User';
async function getUsers() {
const response = await axios.get(
'https://jsonplaceholder.typicode.com/users'
);
return response.data;
}
function Users() {
const [userId, setUserId] = useState(null);
const { data: users, error, isLoading, run } = useAsync({
deferFn: getUsers
});
if (isLoading) return <div>로딩중..</div>;
if (error) return <div>에러가 발생했습니다</div>;
if (!users) return <button onClick={run}>불러오기</button>;
return (
<>
<ul>
{users.map(user => (
<li
key={user.id}
onClick={() => setUserId(user.id)}
style={{ cursor: 'pointer' }}
>
{user.username} ({user.name})
</li>
))}
</ul>
<button onClick={run}>다시 불러오기</button>
{userId && <User id={userId} />}
</>
);
}
export default Users;
정리
- 로그인 할 때는 최상위 컴포넌트에 쿠키를 state에 담고 상태를 관리해준다.(로그아웃, 프로필 수정)
- 로그아웃 했을 경우(state가 null값이 될 때) 최상위에서 첫 화면 컴포넌트를 return 한다.
- API가 필요한 경우 처음 페이지가 렌더링 될 때 useAsync로 state(리스트, 사진 등)를 만들어준다.
- API 필요 없을 경우 처음 페이지 렌더링 될 때 useEffect를 사용해준다.
- 추가, 수정, 삭제가 필요한 데이터의 경우 reducer를 만들어서 관리한다.(action으로 실행)
728x90
반응형