๐ Suspense์ ์ฌ์ฉํด ์ ์ธ์ ์ผ๋ก ๋ก๋ฉ ํ๋ฉด ๊ตฌํํ๊ธฐ
๋ฆฌ์กํธ์ Suspense
๋ React 16 ๋ฒ์ ์์ ์ฒ์์ผ๋ก ์ ๋ณด์ธ ํ
18 ๋ฒ์ ์ผ๋ก ์ค๋ฉฐ ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
์ด ๊ธ์์๋ React 18
์์์ Suspense
๋ฅผ ์, ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ์๊ฐํฉ๋๋ค.
์ด๋ฒ์ ๋ฉ์ด์ ๋ฒ์ ์ด ์ ๋ฐ์ดํธ ๋ react-query v5์์ Suspense๊ฐ ์ด๋ป๊ฒ ๋ฌ๋ผ์ก๋์ง ๋ค์ ๊ธ๋ก ๋น ๋ฅด๊ฒ ์ดํด๋ณด์ธ์!
react-query v5 ์ฃผ์ ๋ณ๊ฒฝ์ ์์๋ณด๊ธฐ feat. Suspense, ErrorBoundary
๐ Suspense๋ฅผ ์ฌ์ฉํ๋ ์ด์
๋ฆฌ์กํธ๊ฐ ํจ์ํ ์ปดํฌ๋ํธ๋ฅผ ๋์
ํ๋ฉฐ ๋ด์ธ์ด ๊ฐ์ฅ ๊ฐ๋ ฅํ ํค์๋๋ ์ ์ธํ ํ๋ก๊ทธ๋๋ฐ
์
๋๋ค.
์ฐ์ ๋ณธ๊ฒฉ์ ์ธ ์ค๋ช
์ ์์ ๋๋น๋๋ ๋ช
๋ นํ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์ ์ธํ ํ๋ก๊ทธ๋๋ฐ์ ์ฐจ์ด์ ๋ํด ์ค๋ช
๋๋ฆฝ๋๋ค.
๐ ๋ช ๋ นํ vs ์ ์ธํ ํ๋ก๊ทธ๋๋ฐ
๊ฐ์ฅ ํํ๊ฒ ํํํ๊ธฐ๋ก๋ ํ ์์
์ ๋ํด
๋ช
๋ นํ์ ์ด๋ป๊ฒ
ํ ๊ฒ์ธ์ง,
์ ์ธํ์ ๋ฌด์์
ํ ๊ฒ์ธ์ง ๋ฐฉ๋ฒ์ ์ฐจ์ด๊ฐ ์๋ค๊ณ ํฉ๋๋ค.
์ ๋ง ์ ๋งคํ ํํ์
๋๋ค.
์ฐ์ ์ฝ๋๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
// ::๋ช
๋ นํ::
const array = [ 1, 2, 3 ]
let sum = 0;
array.forEach( num => sum += num );
console.log(sum);
// ::์ ์ธํ::
const array = [ 1, 2, 3 ];
// ์ด๋๊ฐ์ ์ ์ธ๋์ด ๋ฐฐ์ด์ ํฉ์ ๊ตฌํด์ฃผ๋ arraySum ํจ์
const sum = arraySum(array);
console.log(sum)
๋ช
๋ นํ์ ๊ณผ์ ์ ๋์ด๋์ ๊ฒฐ๊ณผ๋ฅผ ๋์ถํ๋ ๊ฒ์ด๊ณ
์ ์ธํ์ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ํ ๊ธฐ๋ฅ์ ์ถ์ํํ์ฌ ๊ณผ์ ์ ์จ๊ธฐ๊ณ ๋ฌด์์ ํ ๊ฒ์ธ์ง์ ์ง์คํ๋ ๊ฒ์
๋๋ค.
์ฆ, ์ ์ธํ์ ์ด๋๊ฐ์ ๋ช
๋ นํ์ผ๋ก ์ถ์ํ๋ ๊ธฐ๋ฅ์ ์ด์ฉํด ๊ณผ์ ์ ์จ๊ธฐ๊ณ ,
๋ฌด์์ ํ๋์ง ํ์์๋ง ์ง์คํ๋ ๊ฒ์
๋๋ค.
์๋ฅผ ๋ค์ด console.log()
๋ alert()
๋ ์ฐ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง๋ ๊ด์ฌ ์์ด,
"์ฝ์์ ์ฐ๊ธฐ ์ํด", "์ผ๋ฟ์ ๋์ฐ๊ธฐ ์ํด" ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
๐ ๋ฆฌ์กํธ์ ์ ์ธํ
๊ทธ๋ผ ๋์์์ ๋ฆฌ์กํธ์์๋ ์ถ์ํ๋ hook
์ด๋ผ๋ ๊ฒ์ ์ด์ฉํด ์ ์ธ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์์ต๋๋ค.
์ํ๋ฅผ ๊ด๋ฆฌํ๋ ค ํ ๋๋ useState()
,
๋ถ์ํจ๊ณผ(side effect
)๋ฅผ ๊ด๋ฆฌ ๋ฐ ์ฌ์ฉํ๋ ค ํ ๋๋ useEffect()
,
์ฌ์ง์ด ๊ฐ๋จํ ๋ฌธ๋ฒ๋ง ๋ง์ถฐ์ฃผ๋ฉด ์์์ ๋ ๋๋ง๊น์ง ํด์ฃผ๋ ์ฌ๊ธฐ์ ๊ธฐ ์ ์ธํ์ด ์๋ ์ ์์ต๋๋ค.
export const ConditionalRendering = () => {
const [state, setState] = useState<{ name: string }>();
useEffect(() => {
promiseFun().then(response => setState({ name: response }));
}, []);
return state ? <Component name={state.name} /> : <Loading />;
};
๊ทธ๋ฐ๋ฐ ์ง๊ธ๊น์ง ๋น๋๊ธฐ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ fetching
ํด์ค๋ฉฐ ๋ก๋ฉ ์ํ์ ํ๋ฉด์ ๊ทธ๋ฆด ๋๋
์์ ๊ฐ์ด ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ด์ฉํ ๋ช
๋ นํ ์ฝ๋๋ฅผ ์์ฑํด ์์ต๋๋ค.
์ด๋ ๊ฒ ๊ฐ ์ํฉ๋ณ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ค ๋ณด๋ฉด ์ํ๊ฐ ๋ง์์ง๋ฉด ๋ง์์ง์๋ก
๊ฒฝ์ฐ์ ์๋ ๋น๋กํด์ ๋์ด๋ ์ฝ๋๊ฐ ์ง์ ๋ถํด์ง๊ณ ๋ณต์กํด์ง ๊ฒ์ด ๋ปํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ Suspense
๋ฅผ ์ด์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ฐ๋จํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
const SubComponent = () => {
const { data } = useQuery(['serverData'], getFetchData, { suspense: true });
return <div>{data}</div>;
};
const ParantComponent = () => {
return (
<Suspense fallback={ <Loading /> }>
<SubComponent />
</Suspense>
);
};
๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ์์ ์ปดํฌ๋ํธ๋ฅผ Suspense
๋ก ๊ฐ์ธ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋์
๋๋ค.
๋ก๋ฉํ๋ฉด ์ฒ๋ฆฌ๊ฐ ํ์ํ ์ปดํฌ๋ํธ์ ์ ์ธ์ ์ผ๋ก Suspense
๋ฅผ ์ด์ฉํจ์ผ๋ก์จ
๋ก๋ฉ์ ๊ด๋ จ๋ ๋ก์ง์ ์์ํ๊ฒ ๋๊ณ ,
์์ ์ปดํฌ๋ํธ์๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ์ ๋ํด ์ ๊ฒฝ ์ฐ์ง ์๊ณ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ด
๊ด์ฌ์ฌ ๋ถ๋ฆฌ์ ๋ฐ๋ฅธ ์ด๋์ ์ทจํ ์ ์์ต๋๋ค.
๐ Suspense ์ฌ์ฉ๋ฐฉ๋ฒ
๐ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์ฒ์์ ๋์ถฉ ํ์ธํ๊ณ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ๊ธฐ๋ง ํ๋ฉด Suspense๋ฅผ ์ด์ฉํ ์ ์์ ์ค ์์๋๋ฐ
์๊ณ ๋ณด๋ ๊ธฐ๋ฅ์ ์ง์ํ๋ ํน์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์์ต๋๋ค.
- Relay: graphQL์ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- SWR: ์๋ฒ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- React-Query: ์๋ฒ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- Recoil: ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
Suspense
์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด ๋ก๋ฉ ๋ก์ง์ ์งค ์ ์๋ ์ด์ ๋Suspense
๊ฐ Promise
๋ฅผ catch
ํ๋๋ฐ
์์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ Promise
์ํ๋ฅผ throw
ํด์ฃผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Promise
๊ฐ resolve
๋๊ธฐ ์ ๊น์ง Suspense
๊ฐ fallback UI
๋ฅผ ๋ณด์ฌ์ค ์ ์๊ฒ ๋ฉ๋๋ค.
๐ React-Query + Suspense ์ฌ์ฉ๋ฐฉ๋ฒ
graphQL
์ ๋ชจ๋ฅด๋๊น ํจ์คํ๊ณ , Recoil
์ ํด๋ผ์ด์ธํธ ์ ์ญ ๋ฐ์ดํฐ ๊ด๋ฆฌ๋ง ๋ด๋นํ๊ฒ ํ๊ณ ,
๋จ์ ๊ฑด ๋ ๋ฟ์ธ๋ฐ ๋์ธ๋ React-Query
๊ธฐ ๋๋ฌธ์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์์ ๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
react-query์ ๋ํ ์์ธํ ์ค๋ช
์ ์๋ ๊ธ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
[React] react-query, ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์
โก๏ธ react-query๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์ ๋ฆฌ์กํธ์์ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฌด์ํ ๋ง์ต๋๋ค. ๋ํ์ ์ผ๋ก redux, recoil ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋๋ฐ, ๋๋ถ๋ถ ์ด๋ฌํ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ
lasbe.tistory.com
const queryClient = new QueryClient();
root.render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
);
์ฑ์ ๋ฃจํธ ๋ถ๋ถ์ Provider
์ค์ ์ ํด์ฃผ์ด React-Query ์ฌ์ฉ ์ค๋น๋ฅผ ํฉ๋๋ค.
const { data } = useQuery(["serverData"], () => getFetchData(2000), {
suspense: true
});
useQuery ํ
์๋ ( [key]
, fetch ์ฝ๋ฐฑ ํจ์
, ์ต์
) ์ ์ธ์๋ก ๋ฃ์ ์ ์์ต๋๋ค.
ํค๋ ๋ฐฐ์ดํํ๋ก ๋ฃ์ด์ค์ผ ํ๋ฉฐ ์ฝ๋ฐฑ ํจ์์๋ ๋ฐ์ดํฐ๋ฅผ fetch ํ๋ ํจ์๊ฐ ํ์ํ๊ณ
์ต์
์๋ suspense: true
์ต์
์ ์ค์ผ ๋ฐ์ดํฐ fetching์ Suspense๊ฐ ๋์ํฉ๋๋ค.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
suspense: true,
},
},
})
๋ง์ฝ ์ ์ญ์ผ๋ก useQuery
ํ
์ suspense
์ต์
์ ์ฃผ๊ณ ์ถ๋ค๋ฉด ํด๋ผ์ด์ธํธ์ defaultOptions
๋ฅผ ์ด์ฉํ๋ฉด ๋ฉ๋๋ค.
import { useQuery } from "@tanstack/react-query";
import { Suspense } from "react";
const getFetchData = async ({ delay }: { delay: number }) => {
await new Promise((resolve) => setTimeout(resolve, delay));
const data = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
).then((response) => response.json());
return data;
};
type ComponentType = {
delay: number;
};
const SubComponent = ({ delay }: ComponentType) => {
const { data } = useQuery(
["serverData"],
() => getFetchData({ delay: delay }),
{ suspense: true }
);
return <div>{JSON.stringify(data)}</div>;
};
export const App = () => {
return (
<Suspense fallback={<h1>Loading...</h1>}>
<SubComponent delay={2000} />
</Suspense>
);
};
๊ฐ๋จํ๊ฒ ์์ฑํด ๋ณธ ์์ ์
๋๋ค.
jsonplaceholder์์ ๋ฐ์ดํฐ๋ฅผ fetch
ํด์ค๊ณ ์๋์ ์ผ๋ก ๋๋ ์ด๋ฅผ ์ค ์ํํ ๋ก๋ฉํ๋ฉด ํ์๋ฅผ ๋์์ต๋๋ค.
ํ์ธํ๋ฉด ์ ์์ ์ผ๋ก ๋ก๋ฉํ๋ฉด ํ์๊ฐ ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๐ ๋ ๋๋ง ์๋ฃ ์์ ์ด ๋ค๋ฅธ ์ปดํฌ๋ํธ
๋ ๋๋ง ์๋ฃ ์์ ์ด ์๋ก ๋ค๋ฅธ ์ปดํฌ๋ํธ๋ค์ Suspense๋ฅผ ์ด์ฉํด
๋ก๋ฉ ์ฒ๋ฆฌ๋ฅผ ํ๋ ค๊ณ ํ ๋ ํฌ๊ฒ 3๊ฐ์ง ๋ฐฉ๋ฒ์ด ์กด์ฌํฉ๋๋ค.
๐ ๋ค๋ฅธ Suspense์ ๋ฐฐ์น
<>
<h1>Title</h1>
<Suspense fallback={<h2>Title Loading...</h2>}>
<Title delay={2000} />
</Suspense>
<hr />
<h1>Body</h1>
<Suspense fallback={<h2>Body Loading...</h2>}>
<Body delay={6000} />
</Suspense>
</>
์๋ก ์ฐ๊ด์ฑ์ด ์ ์ ์ปดํฌ๋ํธ์ผ ๊ฒฝ์ฐ ๋ค๋ฅธ Suspense ์์ญ์ผ๋ก ๋ฌถ์ด
๊ฐ๋ณ์ ์ธ ๋ก๋ฉํ๋ฉด์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
๐ ๊ฐ์ Suspense ์์ญ์ ๋ฐฐ์น
<>
<h1>Post</h1>
<Suspense fallback={<h2>Post Loading...</h2>}>
<Title delay={2000} />
<Body delay={6000} />
</Suspense>
</>
๊ฐ์ Suspense ์์ ์ปดํฌ๋ํธ๋ฅผ ๋ฐฐ์นํ๋ฉด
์ผ์ฒด๊ฐ ์๊ฒ ๋ก๋ฉ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ง๋ง ์น๋ช
์ ์ธ ๋จ์ ์ด ํ๋ ์์ต๋๋ค.
๋ฐ๋ก ์์ ์ปดํฌ๋ํธ๋ค์ด ์๋ฌด๋ฆฌ ๋นจ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋๋ผ๋
๊ฐ์ฅ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ ๊น์ง ๊ธฐ๋ค๋ ค์ผ ํ๋ค๋ ๊ฒ์
๋๋ค.
์์์๋ Title
์ปดํฌ๋ํธ๊ฐ 2์ด ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ด๋
6์ด์ ์ง์ฐ์๊ฐ์ ๊ฐ๊ณ ์๋ Body
์ ์ํด ๋ ๋๋ง์ด ์๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๐ Suspense In Suspense
์ฌ๋ฌ ์ปดํฌ๋ํธ๋ค์ ๊ฐ๋ณ์ ์ธ Suspense๋ฅผ ์ด์ฉํ๋ฉด n๊ฐ์ Loading UI๊ฐ ํ์๋๋๋ฐ,
์ด๋ค ํ๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ๊ธด ์๊ฐ์ด ๊ฑธ๋ ค๋ ํ๋์ ๋ก๋ฉ์ผ๋ก ๊ตฌํํด์ผ ๋ ๋๊ฐ ์์ ๊ฑฐ๋ผ ์๊ฐํฉ๋๋ค.
๊ทธ๋ด ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ ๊ธด ์๊ฐ์ด ์์๋๋ ์ปดํฌ๋ํธ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌํ ์๋ ์์ต๋๋ค.
<>
<h1>Post</h1>
<Suspense fallback={<h2>Post Loading...</h2>}>
<Suspense fallback={<h2>Profile Image Loading...</h2>}>
<Image delay={8000} />
</Suspense>
<Title delay={2000} />
<Body delay={4000} />
</Suspense>
</>
Promise ์ํ๋ฅผ throw ํ๋ฉด ๊ฐ์ฅ ๊ฐ๊น์ด Suspense๊ฐ catchํ๊ธฐ ๋๋ฌธ์
๋ด๋ถ์ ์ ์ธ๋ Suspense๊ฐ Promise ์ํ๋ฅผ catch ํด์ ๋ถ๋ชจ Suspense๊น์ง ๋๋ฌํ์ง ๋ชปํ๊ฒ ํฉ๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ์ Promise๊ฐ resolve ๋์ง ์์์ด๋ ์์ Suspense์๊ฒ ๋ก๋ฉ ๊ถํ์ ์์ํด์
์ด๋ฏธ fetching์ด ๋๋ ๋ถ๋ชจ Suspense๋ ๋ ๋๋ง์ ํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋ก๋ฉ ๋ก์ง์ ์ง ๋ค๋ฉด ์๋ง์ fallback UI ๋์ ์ฐ๊ด์ฑ ์๋ ์ปดํฌ๋ํธ๋ผ๋ฆฌ
์ผ๊ด์ฑ ์๊ณ ์์ฐจ์ ์ธ ๋ ๋๋ง์ ๋ณด์ฌ์ค ์ ์์ ๊ฒ๋๋ค.
๐ Suspense + ErrorBoundary ํ๋ก์ ํธ ๋์
Suspense์ ErrorBoundary๋ฅผ ์ค์ ํ๋ก์ ํธ์ ๋์ ํ๊ธฐ ์ํด์๋ ๋ ๋ค์ํ๊ณ ์ด๋ ค์ด ๋ฌธ์ ๋ค๊น์ง ํจ๊ป ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
๋ ๊ด์ฌ์ด ์์ผ์๋ค๋ฉด ๋ค์ ๊ธ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
ErrorBoundary & Suspense, ๊ฑฐ์ ์๋ฒฝํ ์ฌ์ฉ๋ฐฉ๋ฒ ๊ฐ์ด๋
[React] ErrorBoundary & Suspense, ๊ฑฐ์ ์๋ฒฝํ ์ฌ์ฉ๋ฐฉ๋ฒ ๊ฐ์ด๋
๐ ErrorBoundary & Suspense, ๊ฑฐ์ ์๋ฒฝํ ์ฌ์ฉ๋ฐฉ๋ฒ ๊ฐ์ด๋ํ๋์ Errorboundary ๋ฐฑ๊ฐ์ try-catch ์ ๋ถ๋ฝ๋ค.ํ๋ก ํธ ๊ฐ๋ฐ์ ๊ณ์ํ๋ค ๋ณด๋ ๋ค์ํ ์ํฉ์ ๋ง์ฃผ์น๊ฒ ๋์๊ณ , ๊ทธ์ ๋ฐ๋ฅธ ์ ์ ํ ํ๋ฉด ํํ์ ์ค
lasbe.tistory.com
ErrorBoundary๋ฅผ ํตํ ์ ์ธ์ ์ธ ์๋ฌ ํธ๋ค๋ง, react-query๋ฅผ ์ด์ฉํ ์ฌํธ์ถ ๋ฐฉ๋ฒ
[React] ErrorBoundary๋ฅผ ํตํ ์ ์ธ์ ์ธ ์๋ฌ ํธ๋ค๋ง, react-query๋ฅผ ์ด์ฉํ ์ฌํธ์ถ ๋ฐฉ๋ฒ
โก ๋ฆฌ์กํธ์์์ ์๋ฌ ํธ๋ค๋ง ๋ฆฌ์กํธ์ ํ ์ปดํฌ๋ํธ์์ ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ์ ์ ํ ์๋ฌ ํธ๋ค๋ง์ ํ์ง ์๋๋ค๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด๊ฐ ์ค๋จ๋ ์ ์์ต๋๋ค. ์ ๋ ํ์ API ํธ์ถ ๋ก์ง์ try - catch
lasbe.tistory.com
๋๊ธ