๐ค Topic: SWR ๋๋ React Query์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ํ๋๊ฒ ๋ ๋ฐฐ๊ฒฝ ๋ฐ ์์ธ
๐ Why I Stopped Using Reduxโ
The Problem with Single Page Applicationsโ
๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์์ผ๋ก ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ด์ ๋ฐ์ดํฐ๊ฐ ํ๋ฐํธ์๋์ ๋ฐฑ์๋์ ๋ ์์น์ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํ์ต๋๋ค.
๋คํธ์ํฌ ๋๊ธฐ ์๊ฐ์ ์ค์ด๊ธฐ ์ํด ๋ฐ์ดํฐ ์บ์๋ฅผ ์ ์งํ๋ฉด์ ๋ชจ๋ ๊ตฌ์ฑ ์์์์ ์ฌ์ฉํ ์ ์๋๋ก ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ ์ญ์ ์ผ๋ก ์ ์ฅํ๋ ์ต์ ์ ๋ฐฉ๋ฒ์ ์๊ฐํด์ผ ํฉ๋๋ค.
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ํฐ ๋ถ๋ถ์ ์ด์ state bugs, ๋ฐ์ดํฐ ๋น์ ๊ทํ ๋ฐ ์ค๋๋ ๋ฐ์ดํฐ๋ก ๊ณ ํต๋ฐ์ง ์๊ณ ๊ธ๋ก๋ฒ store๋ฅผ ์ ์งํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ถ๋ด์ด ๋ฉ๋๋ค. (A big part of frontend development now becomes burdened with how to maintain our global store without suffering from state bugs, data denormalization, and stale data.)
Redux is not a Cacheโ
Redux ๋ฐ ์ ์ฌํ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๋ ์ฐ๋ฆฌ ๋๋ถ๋ถ์ด ๊ฒช๋ ์ฃผ์ ๋ฌธ์ ๋ ๋ฐฑ์๋ ์ํ์ ๋ํ ์บ์๋ก ์ทจ๊ธํ๋ค๋ ๊ฒ์ ๋๋ค. ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , reducer/action์ ์ฌ์ฉํ์ฌ ์คํ ์ด์ ์ถ๊ฐํ๊ณ , ์ต์ ์ํ์ธ์ง ํ์ธํ๊ธฐ ์ํด ์ฃผ๊ธฐ์ ์ผ๋ก ๋ค์ ๊ฐ์ ธ์ต๋๋ค. ์ฐ๋ฆฌ๋ Redux๊ฐ ๋๋ฌด ๋ง์ ์ผ์ ํ๋๋ก ๋ง๋ค๊ณ ์ด๋ฅผ ์ฐ๋ฆฌ ๋ฌธ์ ์ ๋ํ ํฌ๊ด์ ์ธ ์๋ฃจ์ ์ผ๋ก ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๊ธฐ์ตํด์ผ ํ ํ ๊ฐ์ง ์ค์ํ ์ ์ ํ๋ก ํธ์๋์ ๋ฐฑ์๋ ์ํ๊ฐ ๊ฒฐ์ฝ ์ค์ ๋ก ๋๊ธฐํ๋์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค. ๊ธฐ๊ปํด์ผ ๊ทธ๋ค์ด ์๋ ์ ๊ธฐ๋ฃจ(mirage)๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๊ฒ์ ํด๋ผ์ด์ธํธ-์๋ฒ ๋ชจ๋ธ ์ ๋จ์ ์ค ํ๋์ด๋ฉฐ ์ฒ์์ ์บ์๊ฐ ํ์ํ ์ด์ ์ ๋๋ค. ๊ทธ๋ฌ๋ ๋๊ธฐํ ์ํ๋ฅผ ์บ์ฑํ๊ณ ์ ์งํ๋ ๊ฒ์ ๋งค์ฐ ๋ณต์กํ๋ฏ๋ก Redux๊ฐ ๊ถ์ฅํ๋ ๊ฒ์ฒ๋ผ ์ด ๋ฐฑ์๋ ์ํ๋ฅผ ์ฒ์๋ถํฐ ๋ค์ ์์ฑํด์๋ ์ ๋ฉ๋๋ค.
ํ๋ก ํธ์๋์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์์ฑํ๊ธฐ ์์ํ๋ฉด ๋ฐฑ์๋์ ํ๋ก ํธ์๋ ์ฑ ์ ๊ฐ์ ๊ฒฝ๊ณ๊ฐ ๋น ๋ฅด๊ฒ ํ๋ ค์ง๋๋ค. ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ก์ ์ฐ๋ฆฌ๋ ๊ฐ๋จํ UI๋ฅผ ๋ง๋ค๊ธฐ ์ํด Relationships and Tables ๋ํ ์์ ํ ์ง์์ ๊ฐ์ง ํ์๊ฐ ์์ต๋๋ค . ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทํํ๋ ์ต์ ์ ๋ฐฉ๋ฒ์ ์ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ ์ฑ ์์ ํ ์ด๋ธ์ ์ง์ ๋์์ธํ๋ ์ฌ๋๋ค, ์ฆ ๋ฐฑ์๋ ๊ฐ๋ฐ์์๊ฒ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ฐฑ์๋ ๊ฐ๋ฐ์๋ ๋ฌธ์ํ๋ API ํํ๋ก ํ๋ก ํธ์๋ ๊ฐ๋ฐ์์๊ฒ ์ถ์ํ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
ํ๋ก ํธ์๋ ์ฝ๋์์ ๋ฐฑ์๋ ์ํ ๊ด๋ฆฌ๋ฅผ ์ค๋จํ๊ณ ๋์ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธํด์ผ ํ๋ ์บ์์ฒ๋ผ ์ทจ๊ธํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ํ๋ก ํธ์๋๋ฅผ ์บ์์์ ์ฝ๋ ๋จ์ํ ๋์คํ๋ ์ด ๋ ์ด์ด์ฒ๋ผ ์ทจ๊ธํจ์ผ๋ก์จ ์ฐ๋ฆฌ์ ์ฝ๋๋ ์์ ํ๊ธฐ๊ฐ ํจ์ฌ ๋ ์ฌ์์ง๊ณ ์์ํ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๊ฐ ๋ ์ฝ๊ฒ ์ก์ธ์คํ ์ ์์ต๋๋ค.
๐ A Simpler Approach to Backend Stateโ
- React Query
- SWR
- Apollo Client
์ฐธ๊ณ : Comparison | React Query vs SWR vs Apollo vs RTK Query
๐ How and Why You Should Use React Queryโ
React๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ๋ ์ง๋ฉดํ๋ ๋ฌธ์ ์ค ํ๋๋ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ์ฝ๋ ํจํด์ ๊ฒฐ์ ํ๋ ๊ฒ์ ๋๋ค. React์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ global state๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์์ ์ ํ์ฌ ์ํ๋ฅผ ๊ฒฐ์ ํ๋ ๋ฉ์ปค๋์ฆ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
๋ค์์ Star Wars API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์์ ๋๋ค.
import React, {useState, useEffect} from 'react';
import axios from 'axios';
// regular fetch with axios
function App() {
const [isLoading, setLoading] = useState(false)
const [isError, setError] = useState(false)
const [data, setData] = useState({});
useEffect(() => {
const fetchData = async () => {
setError(false);
setLoading(true);
try {
const response = await axios('http://swapi.dev/api/people/1/');
setData(response.data);
} catch (error) {
setError(true);
}
setLoading(false);
};
fetchData()
}, []);
return (
<div className="App">
<h1>React Query example with Star Wars API</h1>
{isError && <div>Something went wrong ...</div>}
{isLoading ? (
<div>Loading ...</div>
) : (
<pre>{JSON.stringify(data, null, 2)}
</pre>
)}
</div>
);
}
export default App;
์์ ์ฝ๋๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ฐ์ดํฐ๋ฅผ fetchingํ๊ณ ์๋์ง์ ์ด๋ฏธ API์์ ์ค๋ฅ ์๋ต์ ๋ฐ์๋์ง, ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์ธ ๊ฐ์ง์ ๋ค๋ฅธ state๊ฐ ํ์ํ๊ณ useState
์ useEffect
hooks ๋๋ค ํ์ํฉ๋๋ค.
๊ทธ๋ฟ๋ง์ด ์๋๋ผ, React์์ ๋ฐ์ดํฐ fetching๊ณผ ๊ด๋ จ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ฐ์ดํฐ๋ ๋ชจ๋ ์ฑ ์ธ์คํด์ค์์ ๊ณต์ ๋๋ฉฐ ๋ค๋ฅธ ์ฌ๋์ด ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.(Data is shared across all app instance and can be changed by other people.)
- ๋ฐ์ดํฐ๊ฐ "stale"์ผ ์ ์์ผ๋ฉฐ ์๋ก ๊ณ ์ณ์ผ ํฉ๋๋ค. (Data could be โstaleโ and needs to be refreshed.)
- ์์ฒญ ์์ ์ ์ต์ ํํ๊ธฐ ์ํด ๋ฐ์ดํฐ ์บ์ฑ ๋ฐ ๋ฐ์ดํฐ ๋ฌดํจํ ์ฒ๋ฆฌ (Handle caching and invalidating data to optimize the request operation.)
๋ง์ง๋ง์ผ๋ก, API์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ ํ๋ remote state์ ๊ฒฐํฉ๋ ํ ๋ง ๋ฐ ์ฌ์ด๋๋ฐ ๊ตฌ์ฑ๊ณผ ๊ฐ์ ์ฌ์ฉ์์ ๊ธฐ๋ณธ ์ค์ ์ ์ผ๋ฐ์ ์ผ๋ก ์ ์ฅํ๋ local state๋ฅผ ๊ฐ๋ ๋ฌธ์ ๋ ์์ต๋๋ค. (Finally, there is also the problem of having the local state which commonly stores your userโs preferences like theme and sidebar config coupled with the remote state which holds the data fetched from API)
//what global state commonly look like nowadays
const state = {
// local state
theme: "light",
sidebar: "off",
// remote state
followers: [],
following: [],
userProfile: {},
messages:[],
todos:[],
}
local state์ remote state๋ฅผ ๋ถ๋ฆฌํ ์ ์๋ค๋ฉด ์ข์ง ์์๊น์? data fetching์ํด ์์ฑํด์ผ ํ๋ boilerplate ์ฝ๋์ ์์ ์ค์ผ ์ ์๋ค๋ฉด ์ด๋จ๊น์?
One solution would be to create your own custom hook to handle fetching and handling of data. Thatโs a completely valid solution.
Another solution and one that weโll be exploring here in-depth is React Query. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ ๊ฐ์ ๊ฐ๋จํ Hooks์ ํ๋์ ์ ํธ๋ฆฌํฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ์์ฑํด์ผ ํ๋ ์ฝ๋์ ์์ ์ค์ด๋ ๋์์ remote data๋ฅผ ๊ฐ์ ธ์ค๊ณ (fetch), ๋๊ธฐํํ๊ณ (synchronize), ์ ๋ฐ์ดํธํ๊ณ (update), ์บ์ํ๋(cache) ๋ฐ ๋์์ด ์ค๋๋ค.
For example, letโs refactor the Star Wars API example above:
import React from 'react';
import axios from 'axios';
import {useQuery} from 'react-query';
// react-query fetch with axios
function App() {
const { isLoading, error, data } = useQuery('fetchLuke', () =>
axios('http://swapi.dev/api/people/1/'))
return (
<div className="App">
<h1>React Query example with star wars API</h1>
{error && <div>Something went wrong ...</div>}
{isLoading ? (
<div>Retrieving Luke Skywalker Information ...</div>
) : (
<pre>{JSON.stringify(data, null, 2)}
</pre>
)}
</div>
);
}
export default App;
Conclusionโ
React Query๋ remote data๋ฅผ global state์ ๋ฃ์ ํ์๋ฅผ ์์ ํ ์์ ์ฃผ๋ ๋ฐ์ดํฐ ์์ฒญ ๊ด๋ฆฌ๋ฅผ ์ํ ํ๋ฅญํ hook ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ ์์น๋ฅผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ค ์ฃผ๊ธฐ๋ง โโํ๋ฉด ์ถ๊ฐ ์ฝ๋๋ ๊ตฌ์ฑ ์์ด ์บ์ฑ, ๋ฐฑ๊ทธ๋ผ์ด๋ ์ ๋ฐ์ดํธ ๋ฐ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. (You just need to tell the library where you need to fetch your data, and it will handle caching, background updates, and stale data without any extra code or configuration.)
๋ํ React Query๋ useState
๋ฐ useEffect
hooks์ ํ์์ฑ์ ์ ๊ฑฐํ๊ณ ๋ช ์ค์ React Query ๋ก์ง์ผ๋ก ๋์ฒดํฉ๋๋ค.
๐ Does React Query replace Redux, MobX or other global state managers?โ
- React Query๋ ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ์ ๋น๋๊ธฐ ์์ ์ ๊ด๋ฆฌ ํ๋ Server-State ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- Redux, MobX, Zusstand ๋ฑ์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ Client-State ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด์ง๋ง React Query์ ๊ฐ์ ๋๊ตฌ์ ๋น๊ตํ ๋ ๋นํจ์จ์ ์ ๋๋ค.
์ด๋ฌํ ์ ์ ์ผ๋์ ๋๊ณ ์งง์ ๋๋ต์ React Query๊ฐ Client-State์ ์บ์ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋ ๋ฐ ๊ด๋ จ wiring ์บ์ ๋ฐ์ดํฐ๋ฅผ ๋ช ์ค์ ์ฝ๋๋ก ๋์ฒดํ๋ค๋ ๊ฒ์ ๋๋ค.
์์ฉ ํ๋ก๊ทธ๋จ์ด ์ค์ ๋ก ์์ฒญ๋ ์์ ๋๊ธฐ ํด๋ผ์ด์ธํธ ์ ์ฉ ์ํ(์: ๋น์ฃผ์ผ ๋์์ด๋ ๋๋ ์์ ์ ์ ์์ฉ ํ๋ก๊ทธ๋จ)๋ฅผ ๊ฐ์ง ์ ์๋ ์ํฉ์ด ์ฌ์ ํ ์์ผ๋ฉฐ, ์ด ๊ฒฝ์ฐ ์ฌ์ ํ Client-State ๊ด๋ฆฌ์๊ฐ ํ์ํ ๊ฒ์ ๋๋ค. ์ด ์ํฉ์์ React Query๋ local/Client State ๊ด๋ฆฌ๋ฅผ ๋์ฒดํ์ง ์๋๋ค๋ ์ ์ ์ ์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ฌธ์ ๊ฐ ์๋ ๋๋ถ๋ถ์ ํด๋ผ์ด์ธํธ ์ํ ๊ด๋ฆฌ์์ ํจ๊ป React Query๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ ๋ฆฌ๋์ค ์ ์ฐ๊ณ ๊ณ์๋์?โ
API์์ฒญ์ ์ด์ react-query, SWR์๊ฒ ๋งก๊ธฐ์โ
๋ฆฌ๋์ค๋ก ์์ฒญ์ ๊ด๋ จ๋ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ค๋ฉด ์์ฒญ ์์, ์์ฒญ ์ฑ๊ณต, ์์ฒญ ์คํจ์ ๋ํ 3๊ฐ์ง ์ก์
๋ค์ ์ค๋นํด์ผ ํ๊ณ ํด๋น ์ก์
๋ค์ ์ฒ๋ฆฌํ๋ ๋ก์ง๋ค๋ ์ค๋นํด์ค์ผ ํ๋ค. (ex. getEpisode
, getEpisodeSuccess
, getEpisodeError
)
2020๋ ์๋ react-query์ SWR ๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ๋ฆด๋ฆฌ์ฆ๋์๋ค. ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชจ๋, Hook์ ์ฌ์ฉํ์ฌ API ์์ฒญ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ , ๋ ์บ์ ๊ด๋ฆฌ๋ ์์ฃผ ๋ฉ์ง๊ฒ ํด๋ธ๋ค.
SWR์ Next.js๋ฅผ ๋ง๋ Vercelํ์์ ๋ง๋ ๊ฒ์ด๊ธฐ์ ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง์ ํ๋ ๊ฒฝ์ฐ Next.js ์ ํจ๊ป ์ฌ์ฉํด์ผํ๋ค (์ ์ด๋ ๊ณต์ ๋ฌธ์์์๋ ํด ๋น ๋ด์ฉ๋ง ๋ค๋ฃฌ๋ค.).
๊ทธ๋ผ์๋ ๋ฆฌ๋์ค ๋ฏธ๋ค์จ์ด๋ ํ์ํ ๊น?โ
ํน์ ๊ธฐ๋ฅ๋ค์ ๋ฏธ๋ค์จ์ด์ ํ์ ๋น๋ ธ์ ๋ ๋์ฑ ์ฝ๊ฒ ๊ฐ๋ฐ ํ ์ ์๋ค. ์น์์ redux-saga, ๋ชจ๋ฐ์ผ ์ฑ์์๋ redux-observable์ ์ฌ์ฉํ ๋ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
์ฒซ๋ฒ์งธ ์ํฉ์ ์์ฒญ์ ์ฐ๋ฌ์์ ์ฌ๋ฌ๋ฒ ํ๊ฒ ๋ ๋ ์ด์ ์์ฒญ์ ๋ฌด์ํ๋๋ก ํ๊ณ ๋งจ ๋ง์ง๋ง์ ์์ฒญ๋ง ์ฒ๋ฆฌํ๋๋ก ํ ๋ ๋ก ์ด๋ฌํ ์ํฉ์ redux-saga ์์ takeLatest
, redux-observable ์์ switchMap
์ ์ฌ์ฉํ๋ฉด ์์ฃผ ์ฝ๊ฒ ๋ง์ง๋ง ์์ฒญ์ ๋ํ ์๋ต๋ง ์ฒ๋ฆฌํ๋๋ก ๊ตฌํ์ ํ ์ ์๋ค.
๋๋ฒ์งธ ์ํฉ์ ์ฒซ๋ฒ์งธ ์ํฉ์ ๊ฝค๋ ๋น์ทํ๊ฑด๋ฐ ํน์ ์กฐ๊ฑด์ด ๋ง์กฑ๋์ ๋ ์ด์ ์ ์์ํ ์์ฒญ์ ์ทจ์ํ๋ ์ํฉ์ด๋ค.
์ธ๋ฒ์งธ ์ํฉ์ ํน์ ์ฝ๋ฐฑํจ์๋ฅผ ์ํ๋ ์ก์ ์ด ๋์คํจ์น ๋์ ๋ ํธ์ถํ๋๋ก ๋ฑ๋ก์ ํ๋ ์ํฉ์ด๋ค.
๋ค๋ฒ์งธ ์ํฉ์ ์ปดํฌ๋ํธ ๋ฐ์์ ์ด๋ค ์์ ์ ์ํํ ๋ ์ด๋ค.
๐ React Query ์ดํด๋ณด๊ธฐโ
React Query๊ฐ ๋ง๋ค์ด์ง ๋๊ธฐโ
React ์์ฒด๊ฐ ๋ฐ์ดํฐ๋ฅผ ํจ์นญํด์ค๊ฑฐ๋ ์ ๋ฐ์ดํธ ํ๋ ์ต์ ์ ์ ๊ณตํ์ง ์๊ธฐ ๋๋ฌธ์ ์๋ React ๊ฐ๋ฐ์๋ค์ ๊ฐ์์ ๋ฐฉ์์ผ๋ก http ํต์ ๋ก์ง์ ์ง์ผ ํ๋ค.
Redux ๊ฐ์ ์ ์ญ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ํด๋ผ์ด์ธํธ ์ํ๊ฐ์ ๋ํด์๋ ์ ์๋ํ์ง๋ง, ์๋ฒ ์ํ์ ๋ํด์๋ ๊ทธ๋ ๊ฒ ์ ์๋ํ์ง ์๋๋ค. Server State๋ Client State์ ์์ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค.
- ์๋ฒ ๋ฐ์ดํฐ๋ ํญ์ ์ต์ ์ํ์์ ๋ณด์ฅํ์ง ์๋๋ค. ๋ช ์์ ์ผ๋ก fetching์ ์ํํด์ผ๋ง ์ต์ ๋ฐ์ดํฐ๋ก ์ ํ๋๋ค.
- ๋คํธ์ํฌ ํต์ ์ ์ต์ํ์ผ๋ก ์ค์ด๋๊ฒ ์ข์๋ฐ, ๋ณต์์ ์ปดํฌ๋ํธ์์ ์ต์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๊ธฐ ์ํด fetching์ ์ฌ๋ฌ๋ฒ ์ํํ๋ ๋ญ๋น๊ฐ ๋ฐ์ํ ์ ์๋ค.
์ข์๋ณด์ด๋ ์ โ
- ๋น๋๊ธฐ ๊ด๋ จํ ํ์ดํ์ด ์ ๋ง ๋ง์ด ์ค์ด๋ ๋ค
- Redux๊ฐ์ ์ ์ญ ์ํ ์ ์ฅ์์ store์ ๋๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธ๋๋ ๋ฐ์ดํฐ์ ์ก์ ๋ง ๋จ๊ธธ ์ ์์ด ํฌ๊ธฐ๋ฅผ ์ค์ด๊ณ , Saga๋ ์์ ๋์ฒดํด๋ฒ๋ฆฐ๋ค.
- ์บ์ฑ๊ณผ ๋ฆฌํจ์นญ์ ๊ฐ๋ฐ์๊ฐ ๊ตฌํํ์ง ์์๋ ์์์ ์ง์ํ๋ค.
- ํ๋ถํ ์ต์ ์ ์ ๊ณตํด ๊ต์ฅํ ๋ง์ ๋ถ๋ถ์์ custom์ด ๊ฐ๋ฅํ๋ค.