React Query๋ฅผ ์ฌ์ฉํ๋ ์ด์
React Query
๋ ์๋ฒ์ ๊ฐ Fetching, Cashing, ๋๊ธฐํ, ์๋ฒ ๊ฐ ์
๋ฐ์ดํธ, ์๋ฌ ํธ๋ค๋ง ๋ฑ ๋น๋๊ธฐ ๊ณผ์ ์ ์ง๊ด์ ์ด๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ํ ์ ์๊ฒ ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๊ฐ React๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ง์ฃผํ๊ฒ ๋๋ ์ฌ๋ฌ ๊ฐ์ง ๋ฌธ์ ์ ์ค ์ ์ผ ๋ํ์ ์ธ ํ๋๊ฐ state ์ํ ๊ด๋ฆฌ์ ๊ดํ ๋ถ๋ถ์ธ๋ฐ์. ๋ํ์ ์ผ๋ก React์ ์ ์ญ ์ํ ๊ด๋ฆฌ ๋๊ตฌ์๋ redux
๋ recoil
๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์กด์ฌํ์ง๋ง, ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ํด๋ผ์ด์ธํธ ์ชฝ์ ๋ฐ์ดํฐ๋ค์ ๊ด๋ฆฌํ๊ธฐ์ ์ ํฉํ ์ ์์ด๋ ์๋ฒ ์ชฝ์ ๋ฐ์ดํฐ๋ค์ ๊ด๋ฆฌํ๊ธฐ์ ์ ํฉํ์ง ์์ ์ ๋ค์ด ์์ต๋๋ค.
ํด๋ผ์ด์ธํธ ์ชฝ ์์ฃผ๋ก ์ ์ญ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋๊ตฌ๋ค์ ์ฌ์ฉํ๋ค ๋ณด๋ฉด ์ด๋ ์๊ฐ๋ถํฐ ํด๋ผ์ด์ธํธ ์ํ์ ์๋ฒ ์ํ๊ฐ ํจ๊ป ๊ณต์กดํ๊ฒ ๋๊ณ ๊ทธ ๋ฐ์ดํฐ๋ค์ด ์๋ก ์ํธ์์ฉํ๋ฉด์ ์ ๋งคํ ์ํ์ ๋ฐ์ดํฐ๊ฐ ๋์ด ๋ฒ๋ฆฝ๋๋ค. ์๋ฅผ ๋ค๋ฉด ์๋ฒ์๋ ์ด๋ฏธ ์
๋ฐ์ดํธ๊ฐ ๋ ๋ฒ๋ฆฐ ๋ฐ์ดํฐ๊ฐ ํด๋ผ์ด์ธํธ์์๋ ์
๋ฐ์ดํธ ๋๊ธฐ์ ๋ฐ์ดํฐ๋ก ์ ์ ์๊ฒ ๋ณด์ด๊ฑฐ๋ ์ฌ์ฉ๋๊ณ ์๋ ์ํฉ์ ๋ปํฉ๋๋ค. React query
๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฒ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ค๋ฉด ํด๋ผ์ด์ธํธ ์ํ๋ฅผ ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ ํจ์ฌ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ด ๋ ๊ฒ์
๋๋ค.
React Query
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ข์ ์๋ก๋ ํด๋ผ์ด์ธํธ์ ์ ์ญ ์ํ ๋ฐ์ดํฐ๊ฐ ๋ง์ด ํ์ํ์ง ์์ admin ํ์ด์ง์ ๊ฐ์ ๊ด๋ฆฌํ ํ์ด์ง๊ฐ ์์ต๋๋ค. ๋ง์ฝ ๋์์ ๋ ๋ช
์ ๊ด๋ฆฌ์๊ฐ ๊ฐ์ ํ๋ฉด์ ๋ณด๊ณ ์๋ ์ํฉ์์ ํ ๊ด๋ฆฌ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ๊ฒฝ์ฐ ๋ค๋ฅธ ๊ด๋ฆฌ์๋ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณผ ์ ์์ด์ผ ํฉ๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๋ ํด๋ผ์ด์ธํธ ์ชฝ๋ณด๋ค๋ ์๋ฒ ์ชฝ์์ ๊ด๋ฆฌํ๋๊ฒ ๋ ์ ํฉํ๋ค๊ณ ๋ณผ ์ ์๊ณ React Query
๋ฅผ ์ ์ฉํ๋ค๋ฉด ์ด ๊ตฌ์กฐ๋ฅผ ๋ ๋จ์ํ ์ํฌ ์ ์์ต๋๋ค.
React Query์ ์ฅ์
โ Data Fetching ๋๋ ์ ๋ฐ์ดํธ ๋ก์ง์ ๋จ์ํ ํ ์ ์์ต๋๋ค.
const getServerData = async () => {
const data = await fetch("...").then((response) => response.json());
return data;
};
// Before
export default function App() {
const [data, setData] = useState([]);
useEffect(() => {
getServerData()
.then((result) => setData(result))
.catch((e) => ... );
}, []);
return <div>{JSON.stringify(data)}</div>;
}
// After
export default function App() {
const { data } = useQuery(["dataKey"], getServerData);
return <div>{JSON.stringify(data)}</div>;
}
useState
๊ณผ useEffect
๋ฅผ ์ฌ์ฉํ ์ํ ๊ด๋ฆฌ ๊ณผ์ ์ React query๋ฅผ ํตํด์ ๋จ์ํ ์ํฌ ์ ์์ต๋๋ค. React query
๋ฅผ ์ฌ์ฉํจ๊ณผ ๋์์ ์ฝ๋ ์๋ฅผ ์ค์ผ์ ์๊ณ useEffect
๋ก ์ธํด์ ๋ฐ์ํ๋ Side Effect
๋ฅผ ์ ๊ฑฐํ ์ ์์ต๋๋ค. ํนํ React query
๊ฐ ๋ด์ฅ๋ ๊ธฐ๋ฅ์ผ๋ก ๋ฐ์ดํฐ ๊ด๋ จ ๋ก์ง๋ค์ ์ ๋ถ ์ฒ๋ฆฌํด์ฃผ๊ธฐ์ ํ ํ๋ก์ ํธ์์ ๊ฐ๋ฐ์๋ค์ด ๋์ผํ ๋ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ์๋ก์ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ์ ์ฒด์ ์ธ ํ๋ฆ์ ํ์
ํ๋ ๊ฒ์ด ์ฌ์์ง๊ฒ ๋๊ณ ์์ ํ๋ ์ผ์ด ์ข ๋ ์์ํด ์ง๊ฒ ๋ฉ๋๋ค.
โ ๋๊ธฐ์ ์ผ๋ก ํธ์ถํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ์ํด API๋ฅผ ํธ์ถํ ๋ react query๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋๊ธฐ์ ์ผ๋ก ์ฌ๋ฌ API๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค. ๋ ๋์๊ฐ ๋ง์ฝ ํ๋์ API๋ฅผ ํธ์ถํ๊ธฐ ์ํด ๋ค๋ฅธ API ํธ์ถ์ ๊ฐ์ด ํ์ํ๋ค๋ฉด ๊ทธ๊ฑฐ ๋ํ ๋จ์ํ ์์ผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
// before
const [data1, setData1] = useState();
const [data2, setData2] = useState();
useEffect(()=>{
getServerData().then((results)=>{
setData1(results[0]);
})
},[]);
useEffect(()=>{
if(data1){
getAfterData(data1).then((dataList)=>{
setState2(dataList);
})
}
},[data1]);
// after
const { data: data1 } = useQuery(["data1"], getServerData);
const { data: data2 } = useQuery(["data2", data1], getServerData, {
enabled: !!data1
});
data1
์ด๋ผ๋ ๋ฐ์ดํฐ์ ์กด์ฌ๋ฅผ useEffect
์ if
๋ก ํ์ธํ๋ ๋์ react query์์ ์ ๊ณตํ๋ ์ต์
์ค enabled
๋ผ๋ ์ต์
์ ์ฌ์ฉํ์ฌ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋๋ง API๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
์ด ์ธ์๋ ๋ง์ ์ฅ์ ๋ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- Caching์ ํตํด์ API ์ฝ๊ณผ ์๋ฒ์ ๋ํ ๋ถ๋ด์ ์ค์ฌ์ค์ผ๋ก์จ ์ดํ๋ฆฌ์ผ์ด์ ์ ์๋๋ฅผ ๋์ฌ์ค๋๋ค.
- ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธ ํ ๊ฒฝ์ฐ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ์ ์์ต๋๋ค.
- ๋์ผ ๋ฐ์ดํฐ์ ๋ํ ์ค๋ณต ์์ฒญ์ ์ ๊ฑฐํฉ๋๋ค.
- ๋น๋๊ธฐ ๊ณผ์ ์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ๊ฐ ์ค๋ ๋์๋ค๊ณ ํ๋จ๋ ์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์ค๋ ์์คํ ์ด ์ง์๋ฉ๋๋ค.
- React Hooks์ ์ ์ฌํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ธฐ์ React๋ฅผ ์ฃผ๋ก ์ผ๋ ๊ฐ๋ฐ์๋ค์๊ฒ ์ง์ ์ฅ๋ฒฝ์ด ๋ฎ์ต๋๋ค.
React Query ๊ธฐ๋ณธ ์ค์น ๋ฐ ์ธํ
npm i @tanstack/react-query
React Query
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ QueryClient
์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ์ปดํฌ๋ํธ๋ค์ด๋ app ์ ์ฒด๊ฐ ์ ๊ทผํ ์ ์๋๋ก QueryClientProvider
๋ก ๊ฐ์ธ์ค์ผ ํฉ๋๋ค. ์ฌ๊ธฐ์ client prop์ผ๋ก QueryClient
๋ฅผ ๋๊ฒจ์ค์ผ ํฉ๋๋ค.
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient();
root.render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
);