일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- tag html
- html tag i
- 자식결합자
- reveal in file explorer
- go live
- RGB
- iframe 태그
- Live Server
- not 의사클래스
- focus 의사클래스
- sub태그
- css
- id 선택자
- html
- br 태그
- Checked 의사 클래스
- 인접 형제 결합자
- RGBA
- i 태그
- 일반 형제 결합자
- 전체 선택자
- padding 속성
- 아두이노
- sup태그
- width속성
- iframe
- 임베디드
- html 태그
- height속성
- background-color 속성
- Today
- Total
so woon!
[REACT QUERY] React Query 1 본문
학습일 : 2023. 04. 10
앞서 우리는
index.tsx 에서 이런 구조를 보았다.
<index.tsx>
(themeProvider 안에 있는 모든 것이 theme으로 접근 할 수 있다고 학습 했었다.)
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<ThemeProvider theme={darkTheme}>
<App />
</ThemeProvider>
);
그것과 마찬가지로 react query도 같은 맥락으로
queryClientProvider 안에 있는 모든 것은 queryClient에 접근할 수 있다고 보면 된다!!
리액트 쿼리를 쓴다면 useEffect, useState와 loading useState 들을 지워도 된다.
await, json(). setInfo() 도 없어도 된다.
터미널에 입력후 리액트 쿼리 설치
npm i react-query
설치가 완료되면
queryClient를 만들러 ㄱㄱ
그런 다음 provider를 만들어야 한다.
<index.tsx>
// import 해주고
import {QueryClient, QueryClientProvider} from "react-query";
// queryClient 작성
const queryClient = new QueryClient()
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
// provider 를 만든다 - ThemeProvider, App 컴포넌트를 잘라내고 QueryClientProvider 안에 넣는다.
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={darkTheme}>
<App />
</ThemeProvider>
</QueryClientProvider>
);
이렇게 작성해주면 준비 완료
이제 리액트 쿼리가 우릴 어떻게 도와줄 수 있을까?
리액트 쿼리는 앞서 우리가 코인 api를 fetch 해서 불러오고
json으로 리턴하고 로딩을 멈추고 했던 일련의 과정들을 생략할 수 있게 만들어 준다.
리액트 쿼리를 사용하기 위해선 먼저,
fetcher 함수를 만들어야 한다.
살펴보자
src 폴더 아래에 api.ts 파일을 만들고
fetch 할때 써줬던 코드를 그 안에 넣을 것이다.
<api.ts>
Coins.tsx에서 fetch 했던 부분에서 const response, const json 부분을 잘라서 이곳에 붙여준다.
// fetchCoins 함수는 json data의 promise를 return 한다.
export async function fetchCoins() {
const response = await fetch("https://api.coinpaprika.com/v1/coins");
const json = await response.json();
return json;
}
await과 async를 사용하는 대신 promise를 사용하는게 더 좋을듯 하고
코드가 너무 길기 때문에 아래와 같이 변경해주겠다.
export function fetchCoins() {
return fetch("https://api.coinpaprika.com/v1/coins").then(response => response.json());
}
이제 useQuery라고 불리는 hook을 사용할 것이다.
<Coins.tsx>
Coins에 return 윗부분을 모두 주석처리 해놓고 시작한다.
useQuery는 두개의 argument를 필요로 한다
(1. querykey - query의 고유식별자임 2. fetcher - 아까 api.ts에서 적어준 fetchCoins임)
useQuery의 멋진점은 useQuery라는 hook이 fetcher 함수 fetchCoins를 불러오고
그리고 fetcher 함수가 isLoading이라면 리액트쿼리가 말해준다는 점이다!
또한 fetcher함수가 끝나도 말해준다.
import { useQuery } from "react-query"; // import 해준다.
import { fetchCoins } from "../api"; // 아까 적어준 api.ts를 import 해준다.
function Coins() {
const{ isLoading, data } = useQuery("allCoins", fetchCoins) // useQuery가 리턴하는 것들을 확인하고 받아오기
}
앞서 api.ts에서 fetchCoins는 json을 리턴했다.
따라서 fetchCoins가 끝나면 리액트쿼리는 그 함수의 데이터를
coins.tsx의
const{ isLoading, data } = useQuery("allCoins", fetchCoins)
이곳 data에 넣어줄 것이다.
총정리
useQuery hook은
1.
내가 api.ts에 작성한 fetcher 함수를 부르고,
fetcher 함수가 loading 중이라면
Coins.tsx의
const {isLoading, data} = useQuery("allCoins", fetchCoins)
이부분에서 그것을 알려줄 것이며,
2.
fetcher함수가 끝나면
api.ts에 작성해준 json을
const{ isLoading, data } = useQuery("allCoins", fetchCoins)
이곳의 data에 넣어줄 것이다.
<Coins.tsx>
따라서 return 부분에 loading ? 부분과 coins 부분이 에러가 생기는데(코드를 삭제해줬기 때문)
이 부분은 각각
1. loading? 부분은 useQuery에서 오는 isLoading ? 으로 바꿔주면 되고
2. coins는 useQuery에서 오는 data로 바꿔주면 된다.
* 1, 2를 바꿔주면 typescript가 data가 뭔지 모르기 때문에 coin부분이 빨간줄이 뜨는데
전에 했던 것처럼
function Coins() {
const{isLoading, data} = useQuery<ICoin[]>("allCoins", fetchCoins);
로 작성해주면 된다
또한 data 부분이 빨간줄이 뜨는 것은 data? 로 고쳐주자
고쳐주면 코드는 아래와 같다
<Coins.tsx>
import { useQuery } from "react-query";
import { Link } from "react-router-dom";
import styled from "styled-components";
import { fetchCoins } from "../api";
function Coins() {
const { isLoading, data } = useQuery<ICoin[]>("allCoins", fetchCoins);
return (
<Container>
<Header>
<Title>Thorn Coin</Title>
</Header>
<SwitchTheme>테마 변경</SwitchTheme>
{isLoading ? (
<Loader>로딩중입니다...</Loader>
) : (
<CoinsList>
{data?.slice(0, 100).map((coin) => (
<Coin key={coin.id}>
<Link to={`/${coin.id}`} state={coin}>
<Img
src={`https://cryptocurrencyliveprices.com/img/${coin.id}.png`}
alt=""
/>
{coin.name}
</Link>
</Coin>
))}
</CoinsList>
)}
</Container>
);
}
export default Coins;
<api.ts>
export async function fetchCoins() {
return fetch("https://api.coinpaprika.com/v1/coins").then((response) =>
response.json()
);
}
실행결과는
이전과 같지만 더 좋은점이 생겼다.
1. 리액트쿼리를 사용하기 전 : -> home 화면으로 갈 때 로딩이 생김(로딩 중 문구 출력됨)
2. 리액트쿼리를 사용한 후 : home 화면으로 돌아갈 때 로딩이 생기지 않음
(로딩이 더이상 생기지 않는 이유는 리액트 쿼리가 데이터를 캐시에 저장해두기 때문이라고 한다.)
이로써 리액트 쿼리를 이용하여 data를 쉽게 fetch하였고
더이상 불필요하게 로딩이 생기지 않고
총 9줄의 코드를 생략하는 결과를 얻었다.
너무 뿌듯하고 좋은걸!!!
'React Query > 개념정리' 카테고리의 다른 글
[REACT QUERY] useQuery 의 refetch interval 기능 (0) | 2023.04.12 |
---|---|
[REACT QUERY] React Query 3 (0) | 2023.04.11 |
[REACT QUERY] React Query 2 (0) | 2023.04.10 |