๐ค ์์งlog ๐ค
[REACT] useQuery ์ useMutation ๋ณธ๋ฌธ
๐ก useQuery
API์ฐ๋์ ํนํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก Hook์ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ ๋ก๋ฉ์ ํธํ๊ฒ ๊ตฌํํ๋๋ก ๋์์ค๋๋ค.
๋ฐํ ๊ฐ์ ํ์ฉํ์ฌ ์ฑ๊ณต, ์คํจ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค. ( isFetching, isLoading, error, state ๋ฑ )
Status
- isLoading : ํ์ฌ ๋ฐ์ดํฐ ์์ฒญ ์ค
- isError : ์ค๋ฅ ๋ฐ์
- isSuccess : ๋ฐ์ดํฐ ์์ฒญ ์ฑ๊ณต
- data : ์์ฒญ ์ฑ๊ณตํ ๋ฐ์ดํฐ
- refetch : ๋ค์ ์์ฒญ์ ์์ํ๋ ํจ์
const Ex = () => {
const result = useQuery('posts', postData);
const { data, error, isLoading } = result;
if (isLoading) return <>Loading...</>;
if (error) return alert(Error!);
return <Container>{data}</Container>
}
Option
- staleTime
- fresh -> stale ๊น์ง์ ์๊ฐ
- fresh : ๋ฐ์ดํฐ fetch๊ฐ ๋ง ์ด๋ฃจ์ด์ง ์ํ
- stale : not fresh. ์ค๋๋ ๋ฐ์ดํฐ์ด๋ฏ๋ก ์ ๋ฐ์ดํธ๊ฐ ํ์ํจ.
- fresh ์ํ์์ unmount ์ดํ ๋ค์ mount ๋์ด๋ fetch ํ์ง ์๊ณ fresh ๋ฐ์ดํฐ ์ฌ์ฉ
- ๊ธฐ๋ณธ ๊ฐ์ 0, 0 ~ Infinity๊น์ง ์ค์ ๊ฐ๋ฅ
- cacheTime
- stale ์ํ์ ๋ฐ์ดํฐ๊ฐ unmount ๋ ์ดํ ์บ์ ๋ฐ์ดํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์์๋ ์๊ฐ
- ์๊ฐ์ด ์ง๋๋ฉด ์บ์ ๋ฐ์ดํฐ๋ GC๊ฐ ์์งํจ
- ๊ทธ ์ ์ ๋ค์ mount ๋๋ค๋ฉด fetch ๋๋ ๋์์๋ ์บ์๋ ๋ฐ์ดํฐ ์ฌ์ฉ
- ๊ธฐ๋ณธ ๊ฐ์ 5๋ถ, 0 ~ Infinity๊น์ง ์ค์ ๊ฐ๋ฅ
- refetchOnMount ( boolean | "always" )
- stale ์ผ ๋ ๋ง์ดํธ ์ refetch ์คํ ์ฌ๋ถ
- ๊ธฐ๋ณธ ๊ฐ์ true.
- always ์ผ ๊ฒฝ์ฐ fresh ์ํ์์๋ refetch ํ๋ค.
- retry (boolean | number )
- ์ฟผ๋ฆฌ๊ฐ ์คํจํ์ ๋ ์ฌ์๋ํ๋ ์ต์
- true : ๊ณ์ ์ฌ์๋
- false : ์ฌ์๋ X
- number : ๊ทธ ์ ๋งํผ ์ฌ์๋
- ๊ธฐ๋ณธ ๊ฐ์ 3
- enabled
- true์ธ ๊ฒฝ์ฐ๋ง ์ฟผ๋ฆฌ ์คํ
const Ex = () => {
const result = useQuery('posts', postData, {
//Options
enabled: true,
refetchOnMount: true,
});
);
๐ก useMutation
๋ฐ์ดํฐ๋ฅผ ์์ฑ / ์ ๋ฐ์ดํธ / ์ญ์ ํ ๋ ์ฃผ๋ก ์ฌ์ฉํฉ๋๋ค.
optimistic update์ ํ์ฉํด์ ์ฑ๊ณต์ ์์ํ๋ฉฐ ๋ฏธ๋ฆฌ UI๋ถํฐ ๊ฐฑ์ ํ ์ ์์ต๋๋ค.
Option
- onMutate: (variables:TVariables) => Promise<TContext|void>|TContext|void
- mutationFn์ด ์คํ๋๊ธฐ ์ ์ ๋จผ์ ์คํํ ํจ์์ ๋๋ค.
- mutation ํจ์๊ฐ ์ ๋ฌ๋ฐ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋์ผํ๊ฒ ์ ๋ฌ๋ฉ๋๋ค.
- optimistic update ์ฌ์ฉ ์ ์ ์ฉํ ํจ์์ ๋๋ค.
- ์ฌ๊ธฐ์ ๋ฐํ๋ ๊ฐ์ onError, onSettled ํจ์์ ์ ๋ฌ๋ฉ๋๋ค.
- onSuccess: (data: TData, variables: TVariables, context?: TContext) => Promise<unknown> | void
- mutation()์ด ์ฑ๊ณตํ๋ฉด ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌํ ๋ ์คํ ๋ฉ๋๋ค.
- invalidationQueries(QueryKey)๋ก ํด๋น ์ฟผ๋ฆฌ๋ฅผ invalidate ํ๊ณ refetch
- setQueryData๋ก ์ง์ ์บ์ฑ๋ ์ฟผ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์์ . (Optimistic Update) refetch๊ฐ ์ผ์ด๋์ง ์์.
- mutation()์ด ์ฑ๊ณตํ๋ฉด ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌํ ๋ ์คํ ๋ฉ๋๋ค.
- onError: (err: TError, variables: TVariables, context?: TContext) => Promise<unknown> | void
- mutation์ด ์๋ฌ๋ฅผ ๋ง๋ฌ์ ๋ ์คํ๋ฉ๋๋ค.
- mutation์ด ์๋ฌ๋ฅผ ๋ง๋ฌ์ ๋ ์คํ๋ฉ๋๋ค.
- onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => Promise<unknown> | void
- mutation()์ ์ฑ๊ณต / ์๋ฌ ์ฌ๋ถ์ ์๊ด์์ด ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ๋ฐ์ต๋๋ค.
- mutation()์ ์ฑ๊ณต / ์๋ฌ ์ฌ๋ถ์ ์๊ด์์ด ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ๋ฐ์ต๋๋ค.
- mutationFn (variables: TVariables) => Promise<TData>
- Required
- ๋น๋๊ธฐ ์์ ์ ์ํํ๊ณ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ ํจ์์ ๋๋ค. (์ฝ๊ฒ ๋งํด api ์์ฒญํ๋ ํจ์)
- variables ๋ mutate๊ฐ ์ ๋ฌํ๋ ๊ฐ์ฒด์ ๋๋ค.
Return
- mutate: (variables: TVariables, { onSuccess, onSettled, onError }) => void
- mutation์ ์คํ์ํค๋ ํจ์์ ๋๋ค.
- variables ๋ mutationFn์ ์ ๋ฌํ๋ ๊ฐ์ฒด์ ๋๋ค.
import React from "react";
import axios from "axios";
import { useMutation } from "react-query";
import "./App.css";
function App() {
const fetchAdd = async (info) => {
const { data } = await axios.post(`/add`, info);
return data;
};
const { mutate, isLoading, isSuccess, isError } = useMutation(fetchAdd, {
onMutate: (variables) => {
// variables : {id: 1}
console.log("onMutate", variables);
},
onError: (error, variables, context) => {
// error
},
onSuccess: (data, variables, context) => {
console.log("success", data, variables, context);
},
onSettled: (data, error, variables, context) => {
// end
},
});
const handleSubmit = () => {
// onMutate ์คํ => ์ฑ๊ณต์ onSuccess ์คํ => ๋๋๋ฉด onSettled ์คํ
mutate({ id: 1 });
};
}
export default App;
update ์ดํ Get ์์ฒญ์ ํตํ ์ต์ ํ
- react-query ์ฅ์ ์ผ๋ก Updateํ์ Get ์์ฒญ์ ์๋์ผ๋ก ์งํ ํ ์ ์์ต๋๋ค.
- mutation ํจ์๊ฐ ์ฑ๊ณตํ ๋, unique key๋ฅผ invalidateQueries์ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
- invalidateQueries๊ฐ ์คํ๋๋ฉด ํด๋น Query๋ ๋ฌดํจํ๋๋ฉฐ refetching์ ์๋ํฉ๋๋ค.
- ์ฆ ์ฌ์ฉ์๊ฐ ์๋ก๊ณ ์นจ์ ํ์ง ์์๋ ๋ฐ์ดํฐ๊ฐ ๊ฐฑ์ ๋ฉ๋๋ค.
const queryClient = useQueryClient();
const mutation = useMutation(fetch, {
onSuccess: () => {
// postTodo๊ฐ ์ฑ๊ณตํ๋ฉด todos๋ก ๋งตํ๋ useQuery api ํจ์๋ฅผ ์คํํฉ๋๋ค.
queryClient.invalidateQueries("key");
}
});
- ํด๋น Query์ ๋ํด refetching์ ์ํ์ง ์๊ณ ๋ฌดํจํ๋ง ์ํ๋ค๋ฉด refetchActive ์ต์ ์ ์ฌ์ฉํฉ๋๋ค.
queryClient.invalidateQueries("key", {
refetchActive: false,
});
Optimistic Update
- useMutation์ด ์ฑ๊ณตํ ๊ฒ์ด๋ผ ๊ฐ์ ํ๊ณ ๋ฏธ๋ฆฌ ํ๋ฉด์ UI๋ฅผ ๋ฐ๊พธ๊ณ ๋์, ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ํ์ / ๋กค๋ฐฑํ๋ ๋ฐฉ์์ ๋๋ค.
- setQueryData ์ต์ ์ ์ฌ์ฉํฉ๋๋ค.
import React from "react";
import axios from "axios";
import { useMutation } from "react-query";
import "./App.css";
function App() {
const fetchAdd = async (info) => {
const { data } = await axios.post(`/add`, info);
return data;
};
const queryClient = useQueryClient();
const { mutate, isLoading, isSuccess, isError } = useMutation(fetchAdd, {
onMutate: async (variables) => {
// ์์ฒญํ Query ์ทจ์ ํจ์
// ์ฆ ํด๋น Query์ ๋ํ refetching์ ๋ง๋ ๊ฒ => onMutate์์ ์ํ๋๋ ๊ฒ๋ค์ ๋ฎ์ด์ฐ์ง ์๊ธฐ ์ํด
await queryClient.cancelQueries("key");
// ๊ธฐ์กด Query๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์ ( ์กด์ฌํ์ง ์์ผ๋ฉด undefinde ๋ฐํ )
const previousValue = queryClient.getQueryData("key");
if (previousValue) {
// setQueryData(): Query์ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ์
๋ฐ์ดํธํ๋ ๋๊ธฐ ํจ์ ( Query๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด ์์ฑ )
// ์ ๋ฌ๋ฐ์ variables๊ฐ์ ์ฆ์ ์๋ก์ด ๋ฐ์ดํฐ๋ก ์
๋ฐ์ดํธ
queryClient.setQueryData("key", (oldData) => [...oldData, variables]);
}
// ์ด์ ๊ฐ ๋ฆฌํด
return { previousValue };
},
onError: (error, variables, context) => {
if (context?.previousValue) {
// error๊ฐ ๋ฐ์ํ๋ฉด onMutate์์ ๋ฐํ๋ ๊ฐ์ผ๋ก ๋ค์ ๋กค๋ฐฑ
queryClient.setQueryData("key", context.previousValue);
}
},
onSuccess: (data, variables, context) => {},
onSettled: (data, error, variables, context) => {
// mutation์ด ์๋ฃ๋๋ฉด ์ฑ๊ณต ์ ๋ฌด์ ๊ด๊ณ์์ด ์ฟผ๋ฆฌ๋ฅผ ๋ฌดํจํ ์ํค๊ณ ์๋ก ๊ฐฑ์
queryClient.invalidateQueries("key");
},
});
const handleSubmit = () => {
// onMutate ์คํ => ์ฑ๊ณต์ onSuccess ์คํ => ๋๋๋ฉด onSettled ์คํ
mutate({ id: 1 });
};
}
export default App;
728x90
'๐ React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[REACT] Pagination ๊ตฌํํ๊ธฐ (0) | 2023.08.24 |
---|---|
[REACT] No QueryClient set, use QueryClientProvider to set one(error) (0) | 2023.08.24 |
[REACT] ๋ฌดํ ์คํฌ๋กค (Infinite Scroll) ๊ตฌํํ๊ธฐ (0) | 2023.02.14 |
[REACT] CSS ๋ฐ์ํ ๋ ์ด์์ ๋๋น๋ฅผ ๋๋๋ ๊ธฐ์ค ์ ํ๊ธฐ (0) | 2023.02.10 |
[REACT] Carousel๋ก ๋ฐฐ๋ ์ฌ๋ผ์ด๋ ๊ตฌํํ๊ธฐ (0) | 2023.02.06 |