
๋ฆฌ์กํธ์์ ๋ฐ๋ณต์ ์ธ useEffect ๋์ SWR ์ฌ์ฉํ๊ธฐ
๋ฆฌ์กํธ์์ ๋ฐ๋ณต์ ์ธ useEffect ๋์ SWR ์ฌ์ฉํ๊ธฐ ๊ด๋ จ
๋ฆฌ์กํธ๋ก ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ์์ฑํ๋ค ๋ณด๋ฉด, ๊ฐ์ฅ ๋จผ์ ๋ ์ค๋ฅด๋ ๋ฐฉ๋ฒ์ด โuseEffectโ๋ค. ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋๊ฑฐ๋ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋น๋๊ธฐ API๋ฅผ ํธ์ถํ๊ณ , ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ํ๋ฅผ ์ ๋ฐ์ดํธํด์ ํ๋ฉด์ ๋ฐ์ํ๋ ๋ฐฉ์์ด ๋น๊ต์ ๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋ฌ๋ ํ๋ก์ ํธ๊ฐ ์ปค์ง๊ณ API ํธ์ถ ํ์๊ฐ ๋ง์์ง์๋ก ๋ฐ๋ณต์ ์ธ useEffect
์ฌ์ฉ์ ์ฌ๋ฌ ๋ฌธ์ ์ ์ ์ด๋ํ๋ค. ์๋ฅผ ๋ค์ด, ์๋ก๊ณ ์นจํ ๋๋ง๋ค ๋์ผํ API๊ฐ ์ค๋ณต ํธ์ถ๋๊ฑฐ๋, ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํด ๋คํธ์ํฌ ์์์ ๋ญ๋นํ๋ ์ํฉ์ด ๋ฐ์ํ ์ ์๋ค. ์ด๋ ๊ฒฐ๊ตญ ์๋ฒ ๋ถํ ์ฆ๊ฐ์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํ๋ก ์ด์ด์ง๋ค.

์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๋ณด๋ค ํจ์จ์ ์ผ๋ก ๋ฐ์ดํฐ ํ์นญ์ ๊ด๋ฆฌํ ์ ์๋ SWR ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ณ ๋ คํ ์ ์๋ค. SWR์ โStale-While-Revalidateโ ์ ๋ต์ ํตํด ์๋ ์บ์ฑ๊ณผ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฐฑ์ , ์๋ ๊ฐฑ์ ๋ฑ์ ์ ๊ณตํ์ฌ, useEffect
๋ง์ผ๋ก ๊ตฌํํ๋ ๋นํจ์จ์ ์ธ ๋ฐ์ดํฐ ํ์นญ ๋ก์ง์ ํจ์ฌ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค ์ ์๋ค.
์ด๋ฒ ๊ธ์์๋ useEffect
๋ฐฉ์์ ํ๊ณ๋ฅผ ์ดํด๋ณด๊ณ , SWR์ด ์ด๋ค ๋ฐฉ์์ผ๋ก ์ด๋ฅผ ๋ณด์ํ ์ ์๋์ง ์์๋ณด๊ณ ์ ํ๋ค.
useEffect
๋ฅผ ์ฌ์ฉํ ๋ฐ์ดํฐ ํ์นญ ์ฝ๋์ ๋ฌธ์ ์
import { useEffect, useState } from "react";
function ComponentA() {
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/data") // API๋ฅผ ํธ์ถ
.then((res) => res.json())
.then((result) => setData(result));
}, []);
return <div>Component A Data: {JSON.stringify(data)}</div>;
}
function ComponentB() {
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/data") // ๋์ผํ API๊ฐ ์ค๋ณต ํธ์ถ๋จ
.then((res) => res.json())
.then((result) => setData(result));
}, []);
return <div>Component B Data: {JSON.stringify(data)}</div>;
}
export { ComponentA, ComponentB };
useEffect ํ ์ ๋งค์ฐ ์ ์ฉํ๋ค. ๋ค๋ง ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ฒ ๋๋ฉด ์ฐจ์ธฐ ์ต์ ํ๋ฅผ ๊ณ ๋ฏผํ๊ฒ ๋๋ค. ์ฑ๋ฅ๋ ์์ฝ์ง๋ง, ์๋ก ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ๋ ํ์ด๋ฐ์ ์ฐจ์ด์ ์ํด ๊ฐ ์ปดํฌ๋ํธ์์ ์๋ก ๋ค๋ฅธ ๋ฐ์ดํฐ๋ก ์ํ ์ ๋ฐ์ดํธ๋ฅผ ํ๊ฒ ๋ ์๋ ์๋ค. ์ข ๋ ์์ธํ ๋ค์ฌ๋ค๋ณด์.
์ฝ๋๊ฐ ๊ธธ๊ณ ๋ณต์กํด์ง๋ค
useEffect
๋ฅผ ์ฌ์ฉํ ๋ฐ์ดํฐ ํ์นญ์ ์ผ๊ฒฌ ๋จ์ํด ๋ณด์ด์ง๋ง, ๋ก๋ฉ ์ํ(isLoading
), ์๋ฌ ์ฒ๋ฆฌ(isError
), ๋ฐ์ดํฐ ๋ฐ์(data)์ ๋ชจ๋ ํ๊บผ๋ฒ์ ๋ค๋ฃจ๋ ค๊ณ ํ ๋ ์ฝ๋๊ฐ ๋น ๋ฅด๊ฒ ๋ณต์กํด์ง๋ค. ๊ฒ๋ค๊ฐ ๋ง์ฝ API๊ฐ ์ฌ๋ฌ ๊ฐ๋ผ๋ฉด, useEffect์ useState๊ฐ ๊ณ์ ๋์ด๋ ๊ฐ๋
์ฑ์ด ์ ์ฐจ ๋จ์ด์ง๋ค.
import React, { useState, useEffect } from 'react';
interface User {
id: number;
name: string;
email: string;
}
function UserProfile() {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);
useEffect(() => {
let isMounted = true;
setIsLoading(true);
fetch('https://api.example.com/user/1')
.then((response) => response.json())
.then((data: User) => {
if (isMounted) {
setUser(data);
setIsLoading(false);
}
})
.catch(() => {
if (isMounted) {
setIsError(true);
setIsLoading(false);
}
});
return () => {
isMounted = false;
};
}, []);
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error!</div>;
if (!user) return <div>No data</div>;
return (
<div>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
);
}
export default UserProfile;
์ด ์ฝ๋ ์์ฒด๋ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ด์ง๋ง, ํ๋ก์ ํธ๊ฐ ์ปค์ง์๋ก ๊ฐ์ข ๋ฐ์ดํฐ ๋ณํฉ, ์กฐ๊ฑด๋ถ ์์ฒญ ๋ฑ์ ์ํฉ์ด ์ถ๊ฐ๋๋ฉด์ ์ ์ ๋ ๋ณต์กํด์ง๋ค.
์ค๋ณต ํธ์ถ์ ๋ฐฉ์งํ๊ธฐ ์ด๋ ต๋ค
์๋ฒ์์ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ๊ณต์ ํด์ผ ํ ๋, ๊ฐ ์ปดํฌ๋ํธ๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก API๋ฅผ ํธ์ถํ๋ ๊ตฌ์กฐ๋ผ๋ฉด ์ค๋ณต ์์ฒญ์ด ์ฝ๊ฒ ๋ฐ์ํ๋ค. ๋ณ๋์ ์บ์ฑ ๋ก์ง์ ์๋์ผ๋ก ์์ฑํ์ง ์๋ ํ, ๋์ผํ URL์ ๋ํ API ์์ฒญ์ด ์ฌ๋ฌ ๋ฒ ์คํ๋๋ฏ๋ก ์๋ฒ์ ๋ถํ์ํ ๋ถํ๋ฅผ ์ค๋ค. ๋ํ ์๋ก๊ณ ์นจ ์์๋ ๋งค๋ฒ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ฏ๋ก ๋คํธ์ํฌ ๋ฆฌ์์ค ์ฌ์ฉ์ด ๋นํจ์จ์ ์ด๋ค.
์๋ ๊ฐฑ์ ๊ธฐ๋ฅ์ด ์๋ค
useEffect๋ ์์กด์ฑ ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋ ๋๋ง ์คํ๋๋ค. ๋ง์ฝ ๋คํธ์ํฌ๊ฐ ์ฐ๊ฒฐ๋๊ฑฐ๋ ๋ธ๋ผ์ฐ์ ํญ์ด ๋ค์ ํฌ์ปค์ค๋ ๋๋ง๋ค ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํ๊ณ ์ถ๋ค๋ฉด, ์ถ๊ฐ์ ์ธ ๋ก์ง์ ์ง์ ์์ฑํด์ผ ํ๋ค. ์ด ๋ํ ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด ๋ก์ง์ด ๋ถ์ฐ๋๊ณ ์ค๋ณต๋ผ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง๋ค.
SWR์ ์ ํํ๊ฒ ๋ ์ด์
์ค๋ณต ํธ์ถ์ ๋ฐฉ์งํ๊ณ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๋ค. ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ์ ๊ณตํต๋ ์์ ์ปดํฌ๋ํธ์์๋ง API๋ฅผ ํธ์ถํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ์ ์ปดํฌ๋ํธ์ props๋ก ์ ๋ฌํ๋ ๋ฐฉ์์ด๋ค. ๋๋ Redux ๊ฐ์ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ์ฌ, ์ ์ญ ์คํ ์ด๋ฅผ ๋ฐ์ดํฐ ์ ์ฅ์๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.
๊ฐ์ธ์ ์ผ๋ก Redux๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝํ์ด ํฌ๊ฒ ๋์์ง๋ ์์์ง๋ง, Action, Reducer, Dispatch, Subscribe ๋ฑ ๋ง์ ์ฝ๋๊ฐ ํ์ํ๊ณ , ๊ตฌ์กฐ๊ฐ ๋ณต์กํด์ง๋ค๋ ์ ์ ๊ณต๊ฐํ๋ค. ๋ํ API ์์ฒญ ์ํ๋ฅผ Redux์์ ๊ด๋ฆฌํ๋ ค๋ฉด redux-thunk ๋๋ redux-saga ๊ฐ์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ถ๊ฐํด์ผ ํ๊ณ , ์๋ ์บ์ฑ์ด๋ ์ค๋ณต ์์ฒญ ๋ฐฉ์ง ๊ฐ์ ๊ธฐ๋ฅ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณต๋์ง ์๋๋ค. ์ด๋ฐ ์ ์์ Redux๋ API ์์ฒญ ์ต์ ํ๋ณด๋ค๋ ์ ์ญ ์ํ ๊ด๋ฆฌ๋ฅผ ์ํ ๋๊ตฌ๋ผ๋ ์ ์ ๊นจ๋ฌ์๋ค.
์ด๋ฌํ ๊ณ ๋ฏผ ๋์ SWR์ ์ฌ์ฉํ๊ฒ ๋์๋ค. SWR์ API ์์ฒญ์ ์๋์ผ๋ก ๊ด๋ฆฌํ๋ฉฐ, ์บ์ฑ, ๋ฐ์ดํฐ ๋๊ธฐํ, ์ค๋ณต ์์ฒญ ๋ฐฉ์ง ๋ฑ์ ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ค. ํนํ ํ์ํ ์ปดํฌ๋ํธ์์ ์ง์ API๋ฅผ ํธ์ถํ๋ฉด์๋ ์ค๋ณต ์์ฒญ์ ๋ฐฉ์งํ ์ ์๋ค๋ ์ ์์ ๋ด๊ฐ ์ํ๋ ๋ฐฉ์๊ณผ ์ ๋ง์๋ค. Redux์ฒ๋ผ ๋ณ๋์ ์ํ ๊ด๋ฆฌ ๋ก์ง์ ์์ฑํ์ง ์์๋ ๋๊ณ , ๋ฐ์ดํฐ๊ฐ ์ต์ ์ํ๋ก ์ ์ง๋๋ฉฐ ์๋์ผ๋ก ๊ฐฑ์ ๋๋ ์ ์ด SWR์ ๋์ฑ ๋งค๋ ฅ์ ์ธ ๋๊ตฌ๋ก ๋ง๋ค์๋ค.
๊ฒ๋ค๊ฐ ๊ธฐ์กด ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ ํ ๋์ฒดํ์ง ์๊ณ , ๋ณด์์ ์ผ๋ก ํจ๊ป ์ฌ์ฉํ ์๋ ์๋ค๋ ์ ๋ ๋ง์์ ๋ค์๋ค. API ์์ฒญ ๋ฐ ๋ฐ์ดํฐ ์บ์ฑ์ SWR์ด ๋ด๋นํ๊ณ , Redux ๊ฐ์ ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ UI ์ํ๋ ํด๋ผ์ด์ธํธ ์ํ ๊ด๋ฆฌ์ ํ์ฉํ๋ ๋ฐฉ์์ด ๊ฐ๋ฅํ๋ค. ์ด๋ฅผ ํตํด ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ ์ ์ด๋ฆฌ๋ฉด์ ๋ ํจ์จ์ ์ธ ์ํ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค๋ ์ ์ด ์ข์๋ค.
SWR์ ๋์ ์๋ฆฌ: Stale-While-Revalidate ์ ๋ต*
SWR์ โStale-While-Revalidateโ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ์ต์ ์ฑ๊ณผ ์ฑ๋ฅ์ ํจ๊ป ํ๋ณดํ๋ค. ๋จ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๋ฐ ๊ทธ์น์ง ์๊ณ , ์บ์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฐฑ์ ์ ํตํด ์ฌ์ฉ์๊ฐ ํญ์ ๋น ๋ฅธ ์๋ต์ฑ๊ณผ ์ต์ ์ ๋ณด๋ฅผ ๋์์ ์ป์ ์ ์๋๋ก ํ๋ค.
์๋ ์บ์ฑ
useSWR ํ ์ ํตํด ํน์ ํค(key)๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ฉด, SWR ๋ด๋ถ์์ ํด๋น ํค์ ํจ๊ป ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ๋ค. ๋ฐ๋ผ์ ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ๋์ผํ ํค๋ก useSWR๋ฅผ ํธ์ถํด๋ ์ค์ API๋ ํ ๋ฒ๋ง ํธ์ถ๋๊ณ , ์ดํ์๋ ์บ์๋ ๊ฒฐ๊ณผ๋ฅผ ์ฆ์ ๋ฐํํ๋ค.
๋ฐฑ๊ทธ๋ผ์ด๋ ๋ฐ์ดํฐ ๋๊ธฐํ
์บ์์ ์ ์ฅ๋ ๋ฐ์ดํฐ๊ฐ ์ฐ์ ํ๋ฉด์ ํ์๋์ง๋ง, ๋์์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ค์ API์ ์ ๊ทผํด ์ต์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๊ฐ์ ธ์จ ์ต์ ๋ฐ์ดํฐ๋ฅผ ํตํด ํ๋ฉด์ ์๋์ผ๋ก ์ ๋ฐ์ดํธํ๋ค. ๋ฐ๋ผ์ ์ฌ์ฉ์๋ ๊ธด ๋ก๋ฉ ์๊ฐ ์์ด ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ๋ฐ๊ณ , ๊ณง๋ฐ๋ก ๊ฐฑ์ ๋ ๋ฐ์ดํฐ๋ก ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ฐ์ดํฐ ์ฌ๊ฒ์ฆ ๋ฐ ๊ฐฑ์
๋ธ๋ผ์ฐ์ ํญ์ด ๋นํ์ฑํ๋๋ค๊ฐ ๋ค์ ํ์ฑํ๋๊ฑฐ๋, ๋คํธ์ํฌ๊ฐ ๋๊ฒผ๋ค๊ฐ ๋ค์ ์ฐ๊ฒฐ๋ ๋ SWR์ ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฌ๊ฒ์ฆํ๋ค. ์ด๋ SWR์ ๊ณ ์ ์ค์ ์ธ revalidateOnFocus
, revalidateOnReconnect
๋ฑ์ ํตํด ๊ฐ๋จํ ์ ์ด๊ฐ ๊ฐ๋ฅํ๋ค.
import React from 'react';
import useSWR from 'swr';
interface User {
id: number;
name: string;
email: string;
}
const fetcher = (url: string) => fetch(url).then((res) => res.json());
function UserProfile() {
const { data, error } = useSWR<User>('/api/user', fetcher);
if (error) return <div>Error!</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<p>Name: {data.name}</p>
<p>Email: {data.email}</p>
</div>
);
}
export default UserProfile;
์ ์์์ฒ๋ผ useSWR('/api/user', fetcher)
๋ฅผ ํธ์ถํ๋ฉด, SWR์ /api/user
๋ก ํ ๋ฒ API๋ฅผ ํธ์ถํ ๋ค ํด๋น ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์บ์ฑํ๋ค. ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ๋์ผ ํค๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ณต ์์ฒญ์ ํ์ง ์๊ณ , ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ๋ณด์ฌ์ค๋ค. ํญ ํฌ์ปค์ค๋ฅผ ์ฎ๊ธฐ๊ฑฐ๋ ๋คํธ์ํฌ๊ฐ ์ฌ์ฐ๊ฒฐ๋๋ฉด, ์๋์ผ๋ก ์ต์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์ค๋ ๊ฒ๋ ํฐ ์ฅ์ ์ด๋ค.
๋ฐ์ดํฐ๊ฐ ์์ฃผ ๋ณ๊ฒฝ๋ ํ์๊ฐ ์๋ ์นํ์ด์ง์ SWR์ ์ ์ฉํ ์ฌ๋ก
๊ธฐ์กด ๋ฌธ์ : ๋ถํ์ํ API ์์ฒญ์ผ๋ก ์ธํ ์ฑ๋ฅ ์ ํ
์ผ๋ฐ์ ์ผ๋ก ์น ํ์ด์ง์ ๋ฐ์ดํฐ๋ ์ฌ์ฉ์๋ค์ ํ๋์ ์ํด ์ ๋ฐ์ดํธ๋๋ค. ๋ฐ์ดํฐ๊ฐ ์ ๋ฐ์ดํธ๋๋ ํ๊ท ์ฃผ๊ธฐ๋ ์ฌ์ฉ์๋ค์ ํ๋ ํจํด์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค. ๋ง์ฝ ๋ฐ์ดํฐ๊ฐ ์์ฃผ ๋ณํ์ง ์์์๋ ๋งค๋ฒ useEffect๋ก ๋์ผํ API๋ฅผ ํธ์ถํ๋ฉด, ์๋ก๊ณ ์นจ ์๋ง๋ค ๋ถํ์ํ ์์ฒญ์ด ๋ฐ์ํ๊ณ ์๋ฒ ๋ถํ๊ฐ ์ปค์ง ์ ์๋ค. ๊ฒ๋ค๊ฐ ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ์ค๋ณต์ผ๋ก ๊ฐ์ ์ ๋ณด๋ฅผ ์์ฒญํ๋ค๋ฉด ๋คํธ์ํฌ ๋ฆฌ์์ค ์ฌ์ฉ๋์ด ํฌ๊ฒ ์ฆ๊ฐํ๋ค.
์ต๊ทผ ์ฌ์ด๋ ํ๋ก์ ํธ๋ก ์์ ํ๊ณ ์๋ ํด์์๋ ์ฌ์ฉ์๋ค์ด ์บ๋ฒ์ค์ ํจ๊ป ์ ์ํด์ ๊ฐ์ด ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๊ณ , ๊ทธ ์บ๋ฒ์ค๋ฅผ ์ ์ฅํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ง๋ค๊ณ ์๋ค. ์บ๋ฒ์ค ๋ชฉ๋ก์ ํ๋์ ๋ณด์ฌ์ฃผ๋ ํ ์ด๋ธ ํํ์ ๋์๋ณด๋๊ฐ ์๊ณ , ๊ฐ ํ์ ํด๋ฆญํ๋ฉด ํด๋น ๋์๋ณด๋์ ์ต์ ๋ฒ์ url๋ก ์ด๋ํ๋ ๊ตฌ์กฐ๋ค.
ํ ์ด๋ธ ํ๋จ์๋ ํ์ด์ง๋ค์ด์ ์ด ์๋๋ฐ, ํ์ด์ง๋ฅผ ์ด๋ํ ๋๋ง๋ค API๊ฐ ๋งค๋ฒ ์๋ก ์์ฒญ๋๋ ๊ฒ์ด ๊ณผํ๋ค๋ ์๊ฐ์ด ๋ค์๋ค. ๋ง์ฝ ์ฌ๊ธฐ์ ํํฐ์ ์ ๋ ฌ ๊ธฐ๋ฅ๊น์ง ์ถ๊ฐ๋ก ๊ตฌํ๋๋ค๋ฉด ๋ถํ๋ ๋์ฑ ์ฌํด์ง ๊ฒ ๊ฐ์๋ค. ์ฐพ์๋ณด๋ SWR์๋ ํ์ด์ง๋ค์ด์ ์ ๊ณ ๋ คํ ์ธํฐํ์ด์ค๊ฐ ์กด์ฌํ๋ค. ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด SWR์ ์บ์๋ก ์ธํด ๋ค์ ํ์ด์ง๋ฅผ ํ๋ฆฌ๋ก๋ํด์ฃผ๋ ์ด์ ๋ ์๋ค๊ณ ํ๋ค.
SWR ์ ์ฉ: ์๋ ์บ์ฑ๊ณผ ์ต์ ํ๋ ๋ฐ์ดํฐ ๊ฐฑ์
function App () {
const [pageIndex, setPageIndex] = useState(0);
// React state์ธ ํ์ด์ง ์ธ๋ฑ์ค๋ฅผ ํฌํจํ๋ API URL
const { data } = useSWR(`/api/canvasList?page=${pageIndex}`, fetcher);
// ... ๋ก๋ฉ ๋ฐ ์๋ฌ ์ํ๋ฅผ ์ฒ๋ฆฌ
return <div>
{data.map(item => <div key={item.id}>{item.name}</div>)}
<button onClick={() => setPageIndex(pageIndex - 1)}>Previous</button>
<button onClick={() => setPageIndex(pageIndex + 1)}>Next</button>
</div>
}
- ์๋ ์บ์ฑ:
/api/canvasList?page=${pageIndex}
ํค๋ก ๋ถ๋ฌ์จ ๋ฐ์ดํฐ๋ ์บ์์ ์ ์ฅ๋๋ค. ์ดํ ๊ฐ์ ํค(๋๋ ๋์ผํ ํ๋ผ๋ฏธํฐ)๋ก useSWR๋ฅผ ํธ์ถํ๋ฉด ์ถ๊ฐ API ์์ฒญ ์์ด ์ฆ์ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ์ฌ ๋ ๋๋งํ๋ฏ๋ก ์ฌ์ฉ์๊ฐ ์ฒด๊ฐํ๋ ๋ก๋ฉ ์๊ฐ์ ์ต์ํํ ์ ์๋ค. - ์ต์ ๋ฐ์ดํฐ ๋๊ธฐํ: ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ํญ์ ์ฎ๊ฒผ๋ค๊ฐ ๋์์ค๊ฑฐ๋(
revalidateOnFocus
), ๋คํธ์ํฌ๊ฐ ๋๊ฒผ๋ค๊ฐ ๋ค์ ์ฐ๊ฒฐ๋ ๋(revalidateOnReconnect) ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฌ๊ฒ์ฆํ๋ค. ์ด ์ธ์๋ ๋ฐ์ดํฐ ์๋ ๊ฐฑ์ ์ ์ํ ์ฌ๋ฌ ์ต์ ๋ค์ด ์์ด, ์ํ๋ค๋ฉด ์ธํฐ๋ฒ ๊ฐ ๋ฑ์ ์ธ์ธํ๊ฒ ์ง์ ํ ์ ์๋ค. ์์ธํ API ์ต์ ์ ๋ฌธ์์์ ํ์ธํ ์ ์๋ค. - ๋ถํ์ํ ํธ๋ํฝ ์ ์ฝ: ์ค์ ๋ก ์์ฃผ ๋ณ๊ฒฝ๋์ง ์๋ ๋ฐ์ดํฐ์ ๋ํด ๋งค๋ฒ ์๋ก๊ณ ์นจํ ๋๋ง๋ค API๋ฅผ ๋ค์ ํธ์ถํ์ง ์๋๋ก ํด, ๋คํธ์ํฌ ๋ถํ์ ์๋ฒ ํธ๋ํฝ ๋ชจ๋ ์ค์ด๋ ๋ค.
์ฌ์ค ์ฌ์ด๋ ํ๋ก์ ํธ๋ผ์ API๋ฅผ ํธ์ถํ๋ ์ ์์ฒด๊ฐ ๋ง์ง๋ ์๊ณ , ์ค์ ์ฌ์ฉ์๋ค์ ๊ฒฝํ์ ๋ฃ๊ธฐ ์ด๋ ค์ด ๋ถ๋ถ์ด ์๋ค. ํ์ง๋ง ์ค์ ๋ก API ํธ์ถ์ ๊ฐ์์จ์ ๋ดค์ ๋ ๋์ ๋๋ ๋ณํ๊ฐ ๋ณด์๊ณ , ๋ง์ฝ ์ ์ ๊ฐ ๋ง์์ง๋ค๋ฉด ๊ทธ๋ก ์ธํ ๋น์ฉ์ ํฌ๊ฒ ์ฐจ์ด๊ฐ ๋ ๊ฒ์ด๋ค. ์ฌ์ด๋ ํ๋ก์ ํธ๋ฅผ ํ๋๋ผ๋ ์ค์ ์๋น์ค๋ก์ ํ์ฅ ๊ฐ๋ฅ์ฑ์ ์ผ๋์ ๋๊ธฐ ๋๋ฌธ์, ์ ์๋ฏธํ ๊ฐ์ ์ด๋ผ๊ณ ํ๋จํ๋ค.
SWR๋ก ํจ์จ์ ์ธ ๋ฐ์ดํฐ ํ์นญ์ ๊ตฌํํ์*
useEffect
๋ฅผ ์ด์ฉํ ์ ํต์ ์ธ ๋ฐ์ดํฐ ํ์นญ ๋ฐฉ์์ ๊ฐ๋จํ๊ฒ ๋ณด์ด์ง๋ง, ๊ท๋ชจ๊ฐ ์ปค์ง์๋ก ์ค๋ณต ํธ์ถ๊ณผ ์ํ ๊ด๋ฆฌ ๋ณต์ก๋ ์ฆ๊ฐ๋ก ์ธํด ์ฑ๋ฅ๊ณผ ๊ฐ๋
์ฑ ๋ฉด์์ ๋ฌธ์ ๋ฅผ ์ผ์ผํจ๋ค. ์ด๋ฅผ ์ ์ญ ์ํ ๊ด๋ฆฌ๋ฅผ ํตํด ํด๊ฒฐํ ์๋ ์์ง๋ง, ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ฐพ๋๋ค๋ฉด SWR์ ๊ณ ๋ คํด ๋ณผ๋ง ํ๋ค. SWR์ โStale-While-Revalidateโ ์ ๋ต์ผ๋ก ์๋ ์บ์ฑ๊ณผ ๋ฐฑ๊ทธ๋ผ์ด๋ ๋๊ธฐํ๋ฅผ ์ ๊ณตํด, ์ด๋ฌํ ๋ฌธ์ ์ ์ ํจ๊ณผ์ ์ผ๋ก ๊ฐ์ ํ๋ค.
๋จ, SWR์ด useEffect
๋ฅผ ์์ ํ ๋์ฒดํ๋ค๊ณ ๋ณผ ์๋ ์๋ค. ์ฌ์ฉ์ ์
๋ ฅ์ด๋ ํน์ ํ ์์กด์ฑ์ ์ํด ์ฆ๊ฐ์ ์ผ๋ก ๋ฐ์ํด์ผ ํ๋ ๋ก์ง์ ์ฌ์ ํ useEffect
๋ ๋ณ๋ ํ
์ด ํ์ํ๋ค. ๊ทธ๋ผ์๋ ๋ฐ๋ณต์ ์ธ API ํธ์ถ๊ณผ ๊ณตํต ๋ฐ์ดํฐ ์ค๋ณต ๊ด๋ฆฌ ๋ฌธ์ ๋ฅผ ๊ฒช๊ณ ์๋ค๋ฉด, SWR์ ์ ๊ทน์ ์ผ๋ก ๋์
ํด ๋ด๋ ์ข๊ฒ ๋ค.
๋ง์ฝ ํ๋ก์ ํธ์์ useEffect
๊ฐ ๋๋ฌดํ๊ณ , API ํธ์ถ์ด ๋ถํ์ํ๊ฒ ์์ฃผ ๋ฐ์ํ๋ ์ํฉ์ด๋ผ๋ฉด SWR์ ์ ์ฉํจ์ผ๋ก์จ โ๊ฐ๋ฐ ํจ์จโ๊ณผ โ์ฑ๋ฅ ๊ฐ์ โ์ด๋ผ๋ ๋ ๋ง๋ฆฌ ํ ๋ผ๋ฅผ ๋ชจ๋ ์ก์ ์ ์์ ๊ฒ์ด๋ค. ์ค์ ํ์
ํ๊ฒฝ์์ ์์ฃผ ๋ณ๊ฒฝ๋์ง ์๋ ํ์ด์ง๊ฐ ์๋์ง ๋๋ฌ๋ณด๊ณ , ์ฐจ๊ทผ์ฐจ๊ทผ SWR์ ์ ์ฉํด ๋ณด๋ ๊ฒ์ ์ถ์ฒํ๋ค.
ยฉ๏ธ์์ฆIT์ ๋ชจ๋ ์ฝํ ์ธ ๋ ์ ์๊ถ๋ฒ์ ๋ณดํธ๋ฅผ ๋ฐ๋ ๋ฐ, ๋ฌด๋จ ์ ์ฌ์ ๋ณต์ฌ, ๋ฐฐํฌ ๋ฑ์ ๊ธํฉ๋๋ค.