react-query를 사용해 본다. 기능
- 캐싱 기능: fresh, fetching, stale, inactive, delete 상태
- stale 상태가 받은 데이터를 캐싱한 상태이다
- QueryClientProvider 설정을 통해 useQuery 훅에 QueryClient를 전달한다.
- 조회
- 생성/수정/삭제
- const { mutate } = useMutation(queryFunction, options);
- mutate(data, callbacks);
- 캐싱 무효화
- const queryClient = useQueryClient();
- queryClient.invalidateQuries(key);
설치 및 설정
react-query를 설치한다.
$> npm install react-query
apps/tube-csr/src/main.tsx에 react-query의 provider를 설정한다. 그리고 ReactQuery의 DevTool도 설치한다.
// main.tsx
import { StrictMode } from 'react';
import * as ReactDOM from 'react-dom';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import App from './app/app';
const queryClient = new QueryClient();
ReactDOM.render(
<StrictMode>
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools />
</QueryClientProvider>
</StrictMode>,
document.getElementById('root')
);
Custom Hook 만들기 및 api 패키지 구성
useQuery를 통해 custom Hook을 만들 수 있다. useQuery 사용시 Typescript에 대한 타입정의를 하자. api 패키지를 별도로 생성하고, dog.api.ts 파일을 생성한다. api custom Hook과 type 파일을 별도로 모아 둔다
$> nx g @nrwl/react:lib api
libs/api/src/lib 폴더 밑에 dog.api.ts 파일을 생성하고, react-query 의 custom Hook을 만든다.
// dog.api.ts
import { useQuery } from 'react-query';
import { httpService } from '@rnn-stack/core';
export function useDogList() {
return useQuery<{ message: string[]; status: string }, Error>('dog-list', () =>
httpService
.get('https://dog.ceo/api/breeds/list')
.toPromise()
.then((response: any) => response)
);
}
dog.api.ts 파일을 libs/api/src/index.ts 에 export 추가한다.
export * from './lib/api';
export * from './lib/api/dog.api';
이제 apps/tube-csr/src/app/dog.tsx 에서 사용해 본다. 기존 코드는 주석 처리하고 useDogList 라는 custom Hook을 사용한다.
useState, useEffect 사용하지 않고 custom Hook을 별도로 작성하였다.
- 코드가 간결해 졌다.
- 역할 분리가 잘 되었다.
- api는 여러곳에서 공통으로 사용하므로 위치투명하게 api 패키지로 이동하였다.
- import { useDogList } from "@rnn-stack/api";
// dog.tsx
import { List } from 'antd';
import { useDogList } from '@rnn-stack/api';
function DogList() {
// const [dogList, setDogList] = useState<string[]>([]);
// useEffect(() => {
// httpService.get('https://dog.ceo/api/breeds/list').subscribe((response: any) => {
// console.log('axios observable response:', response);
// setDogList(response.message);
// });
// }, []);
const { isLoading, data, error } = useDogList();
if (isLoading || !data) {
return <span>loading...</span>;
}
if (error) {
return <span>Error: {error.message}</span>;
}
return (
<List
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={data.message}
renderItem={(item: string) => <List.Item>{item}</List.Item>}
/>
);
}
export default DogList;
현재는 각 라이브러리의 쓰임세와 구조에 대해서 보고 있다. Production에 사용하려면 좀 더 다음어야 할 것으로 보인다. 다음은 상태관리를 위하여 recoil을 적용해 보자.
소스: https://github.com/ysyun/rnn-stack/releases/tag/hh-4
<참조>
>ReactQuery에 대한 장점을 잘 설명준다.
https://swoo1226.tistory.com/216
> react-query & typescript: https://tkdodo.eu/blog/react-query-and-type-script
> react hook & rxjs: https://nils-mehlhorn.de/posts/react-hooks-rxjs
> hooks: https://twitter.com/tylermcginnis/status/1169667360795459584
- useState: Persist value between renders, trigger re-render
- useRef: Persist value between renders, no re-render
- useEffect: Side effects that run after render
- useReducer: useState in reducer pattern
- useMemo: Memoize value between renders
- useCallBack: Persist ref equality between renders
> hook lifecycle: https://medium.com/doctolib/how-to-replace-rxjs-observables-with-react-hooks-436dc1fbd324
'React > Start React' 카테고리의 다른 글
[React HH-6] 서버 사이드 렌더링 SSR - Next.JS (0) | 2021.09.08 |
---|---|
[React HH-5] 라이브러리 설정 - recoil (0) | 2021.09.07 |
[React HH-3] 라이브러리 설정 - Axios, RxJS (0) | 2021.08.28 |
[React HH-2] NX 기반으로 React 개발환경 구성하기 (0) | 2021.08.25 |
[React HH-1] 시작하는 개발자를 위한 히치하이커 (0) | 2021.08.25 |