Data Flows in React - team-yaza/mozi-client GitHub Wiki
๊ฐ์
์ด ๊ธ์ React์ Data Flow
๋ฅผ 3000๋ฏธํฐ ์์์ ๋ฐ๋ผ๋ณด๋ ๊ธ ์
๋๋ค.
๊ธ์ ์์์ผ๋ก React์ ๊ฐ์ SPA๊ฐ ํ์ด์ง๋ฅผ ๋ ๋๋งํ๋ ๋ฐฉ์์ ๋ณด๊ฒ ์ต๋๋ค.
- ์ ์ ๊ฐ ์๋ฒ์ ํ์ด์ง๋ฅผ ์์ฒญํฉ๋๋ค.
- ์๋ฒ๋ React bundle์ด ๋ค์ด์๋ HTML ํ์ผ์ ๋ณด๋ด์ค๋๋ค.
- ๋ธ๋ผ์ฐ์ ๊ฐ React bundle์ fetchingํด์์ React code๋ก ํ์ด์ง๋ฅผ ๊ทธ๋ฆฝ๋๋ค.
- ๋ฐ์ดํฐ๊ฐ ํ์ํ ์ปดํฌ๋ํธ๋ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํฉ๋๋ค. ๋ฐ์ดํฐ๋ ์ ์ ์๊ฒ ๋ฐํ๋๊ณ React๊ฐ ๊ทธ ๋ฐ์ดํฐ๋ก DOM์ ์ ๋ฐ์ดํธํฉ๋๋ค.
์ด ๊ธ์์ ์ด์ผ๊ธฐํ ๋ด์ฉ์ 4
๋ฒ๊ณผ ๊ด๋ จ์ด ๊น์ต๋๋ค.
Data Flow in React
React์์ ๋ฐ์ดํฐ๊ฐ ํ์ํ ์ปดํฌ๋ํธ๋ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ ๋ค์ํฉ๋๋ค.(useEffect, redux..๋ฑ)
์ฐ๋ฆฌ๊ฐ ์์ ๊ฐ์ ์ปดํฌ๋ํธ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๋ค๊ณ ์์ํด๋ณด๊ฒ ์ต๋๋ค.
React๋ ๋จ๋ฐฉํฅ ๋ฐ์ธ๋ฉ
์ ํ๋ฏ๋ก ๋ฐ์ดํฐ๋ ๋ถ๋ชจ์์ ์์์ผ๋ก ํ๋ฆ
๋๋ค.
C, D, E
์ ๊ฐ๊ฐ ๋ฐ์ดํฐ๋ฅผ fetchingํ๋ ๋ก์ง์ด ๋ด๊ฒจ์ ธ ์๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค.
์ฝ๋๋ก ํํํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํํํ ์ ์์ต๋๋ค.(B๋ ์ ์ธ)
function PageA({ userId }) {
return (
<C userId={userId}>
<D userId={userId} />
<E userId={userId} />
</C>
)
}
C
์ ๋ฐ์ดํฐ fetching์ด ๋๋๊ธฐ ์ ๊น์ง.
๋ค์๋งํ๋ฉด C
์ปดํฌ๋ํธ์์ D
์ E
๋ฅผ ๋ ๋๋งํ๊ธฐ ์ ๊น์ง D
์ E
๋ fetching์ ์์์กฐ์ฐจ ํ์ง ์์ต๋๋ค.
์ ๊ทธ๋ฆผ์์ ๋ ์์์๋ React ๋ก๊ณ ๋ฅผ ์์ ์ปดํฌ๋ํธ๋ผ๊ณ ํ๋ฉด ์์ ์ปดํฌ๋ํธ๊ฐ fetching์ด ์์๋๊ณ ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ณ ๋ค์ ํ์ ์ปดํฌ๋ํธ์์ data fetching์ด ์์๋ฉ๋๋ค. ๋์์ ์์ฒญ์ ๋ณด๋ผ ์ ์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ์ฝ๋๋ฅผ ์ง ๋ฐฉ์ ๋๋ฌธ์ ๋์์ ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ ์์ฒด๊ฐ ๋ถ๊ฐ๋ฅํ์ฃ .
์ด๋ฌํ ํ์์ Network Waterfall
์ด๋ผ๊ณ ํฉ๋๋ค.
ํ์ด์ค๋ถ์์๋ ์ด ๋ฌธ์ ๋ฅผ GraphQL๊ณผ Relay๋ฅผ ์ฌ์ฉํด ํด๊ฒฐํ์ต๋๋ค. (๊ฐ๊ฐ์ ์ปดํฌ๋ํธ๋ ์์ ์ด ํ์ํ ๋ฐ์ดํฐ๋ฅผ GraphQL Frament๋ฅผ ํตํด ๊ตฌ์ฒดํํ๊ณ , Relay๋ fragments๋ฅผ ์กฐํฉํ์ฌ ์๋ก์ด ํ์ด์ง๋ก ์ด๋ํ ๋ ์๋ฒ์ ํ๋ฒ์ ํต์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ fetching ํฉ๋๋ค.)
GraphQL์ ์ฌ์ฉํ๋ ค๋ฉด ๋ฐฑ์๋๋ฅผ GraphQL๋ก ๋ง๋ค์ด์ผํ๋ ์ ์ฝ์ด ์กด์ฌํฉ๋๋ค. ๋ค๋ฅธ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์์๊น์?
์ ๋ง ์ฌ์ด ๋ฐฉ๋ฒ์ด ์กด์ฌํฉ๋๋ค.(props drilling)
Props Drilling
useDataFor*()
ํ
์ ๊ฐ๊ฐ์ ์ปดํฌ๋ํธ๊ฐ ํ์๋ก ํ๋ ๋ฐ์ดํฐ๋ฅผ fetchingํ๋ ํ
์
๋๋ค.
useDataForD()
์ useDataForE()
๊ฐ useDataForC()
๋ก๋ถํฐ ์ค๋ ์์ฑ์ ์๊ตฌํ์ง ์๋๋ค๋ฉด useDataForD()
์ useDataForE()
๋ฅผ C
์ปดํฌ๋ํธ์ ๋์ด์ฌ๋ฆฝ๋๋ค.
๊ทธ ํ props drilling
์ผ๋ก ์๋ ์ปดํฌ๋ํธ์ ๋ด๋ ค์ฃผ๋ฉด ๋ฉ๋๋ค.(ํ๋ฒ์ ์์ ์ปดํฌ๋ํธ์์ ๋ชจ๋ ์์ฒญ์ ํ๊ณ props๋ก ๋ด๋ ค์ค๋๋ค.)
ํ์ง๋ง ์ ๊ฒฝ์ฐ๋ ์ด์์ ์ธ ๊ฒฝ์ฐ์
๋๋ค. D
์ E
๋ C
๋ก๋ถํฐ ์ค๋ ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํ ์ ์์ต๋๋ค. ์๋์ ๊ฐ์ด ๋ง์ด์ฃ .
์ด๋ฌํ ๊ฒฝ์ฐ useDataForC()
ํ
์ด ๋ฐ๋ ๋ฐ์ดํฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
c: {
d: "dID"
e: "eID"
}
๊ทธ๋ฆฌ๊ณ D
์ E
๋ ๊ทธ ์์ด๋๋ฅผ ์ด์ฉํ ์์ฒญ์ ๋ณด๋ด๊ณ ๋ค์๊ณผ ๊ฐ์ ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ๊ฒ ์
๋๋ค.
// D๊ฐ ๋ฐ๋ ๋ฐ์ดํฐ
d: {
friends: [...]
}
// E๊ฐ ๋ฐ๋ ๋ฐ์ดํฐ
e: {
songs: [...]
}
์ด ์ํฉ์ ๋ค์ ์ด์์ ์ธ data fetching์ผ๋ก ๋ฐ๊ฟ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฒซ๋ฒ์งธ fetch์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด Join
์ ํ์ฉํ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
ํ์๋ค(๋ฐฑ์๋ ์์ง๋์ด)๊ณผ ๋ํ๋ฅผ ํตํด ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ์๋จ ์ปดํฌ๋ํธ๋ก ์ฌ๋ฆฌ๊ณ ํ์ ์ปดํฌ๋ํธ๊ฐ ๋ฆ๊ฒ ๋ ๋๋ง๋๋ ๊ฒ์ ๋ง์์ผํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด useDataForC()
ํ
์ ํธ์ถํ๋ ๊ฒ์ ํตํด ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ฒ ๋๊ณ props drilling
์ผ๋ก ๋ด๋ ค์ค์ผ๋ก์จ Network Waterfall
์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
Example
์ง๊ธ๊น์ง ์ค๋ช ํ ๋ด์ฉ์ ๋ธ๋ก๊ทธ ๊ธ์ ๋ ๋๋งํ๋ ์ํฉ์ ๊ฐ์ ํด์ ์๋ก ๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
๋ธ๋ก๊ทธ ์ ํ๋ฆฌ์ผ์ด์ ๋ด๋ถ์๋ ๊ธ๋ค(writings)์ด ์๊ณ ๊ธ ์ปดํฌ๋ํธ ๋ด๋ถ์๋ ์์ฑ์์ profile ์ปดํฌ๋ํธ๊ฐ ์์ต๋๋ค.
๊ธ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง์ด ๋์์ง๋ง profile ์ปดํฌ๋ํธ๋ ๊ธ์ด ๋ ๋๋ง์ด ๋ ์ดํ์์ผ ๋ฐ์ดํฐ fetching์ ํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ Network Waterfall
์ ๋ง๋๋ ๊ฒ์ด ์๋, ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ์ต์๋จ์ผ๋ก ๋์ด์ฌ๋ ค์ Props Drilling
ํด์ผํฉ๋๋ค.
React๋ View๋ฅผ ์ ๋ค๋ฃจ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ์๋จ ์ปดํฌ๋ํธ๋ก ๋์ด์ฌ๋ฆผ์ผ๋ก์จ View์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ถ๋ฆฌํ๊ณ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ์ ํ๋ฆ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.(FLUX)
์ด๊ฒ React๊ฐ ์๋ํ Data Flow์ ๋๋ค.
Drastic Props Drilling
๊ณผ๊ฐํ Props Drilling
Props Drilling
์ด ๋์๊ธฐ๋ง ํ ๊ฒ์ผ๊น์?
์ ๋ React์ ํน์ง์ธ ๋จ๋ฐฉํฅ ๋ฐ์ธ๋ฉ
์ ์ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
Props Drilling
์ ํ๋ฉด ๋ฐ์ดํฐ์ ํ๋ฆ์ด ํ๋ฐฉํฅ์ผ๋ก๋ง ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์ ์ถ์ ํ๊ธฐ ์ฝ์ต๋๋ค.
Props Drilling
์ด ์์ข๋ค๊ณ ๋งํ๋ ๊ฒ์ ์์ props๋ค์ด ํ์๋ก ์ ๋ฌ๋๋ ์ ํต๊ณผ์ ์์ ์ค๊ฐ์ ์๋ ์ปดํฌ๋ํธ๊ฐ ๊ทธ props๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด์ ์ค์ง ์ ๋ฌ์ ์ํ ๋งค๊ฐ์ฒด๋ก ์ฌ์ฉ๋ ๋๋ผ๊ณ ์๊ฐํฉ๋๋ค.
Props Drilling
์ ์ฌ์ฉํ๋ฉด ์ปดํฌ๋ํธ๋ฅผ ํ
์คํ
ํ๊ธฐ๋ ์ฌ์์ง๋๋ค. ์์กดํ๋ ๊ฒ์ด props๋ฟ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.(์ ์ญ์ํ, Context, react-query๋ฑ์ ์์กดํ์ง ์์ต๋๋ค.)
์ ์ญ ์ํ์ ์์กดํ์ง ์๋ ์ปดํฌ๋ํธ๋ ์ปดํฌ๋ํธ๋ฅผ ์ปดํฌ๋ํธ๋ต๊ฒ ๊ฐ๋ฐํ ์ ์์ผ๋ฉฐ(์ปดํฌ๋ํธ ์ฃผ๋ ๊ฐ๋ฐ
), ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ฒ ๋์์ค๋๋ค.
๋ชจ๋ React ์ ํ๋ฆฌ์ผ์ด์
์ ์ ์ ํ deps
์ Props Drilling
๊ณผ ๊ฐ ์ปดํฌ๋ํธ์ ์ํ๊ฐ ์กฐํ๋ฅผ ์ด๋ฃจ์ด์ผํ๋ฉฐ, ์ ์ ํ Data Flow
์ ๊ฐ์ ์ ์๋๋ก ๋
ธ๋ ฅํด์ผํฉ๋๋ค.
React-Query
๋ง์ง๋ง์ผ๋ก ๋ฐ์ดํฐ fetching์ ๋งค์ฐ ์ฝ๊ฒํด์ฃผ๋ react-query์ ๋ํ ๋ด์ฉ์ ๋ฃ์์ต๋๋ค.
react-query๋ฅผ ํตํด ์์ ์ปดํฌ๋ํธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ Props Drilling
์ผ๋ก ๋ด๋ ค์ค ์ ์์ต๋๋ค.
React๋ View๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ณ ReactDOM์ UI๋ฅผ ์ค์ ๋ก ๋ธ๋ผ์ฐ์ ์ ๋ ๋๋งํ ๋ ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ fetchingํ๋ ๊ฒ์๋ ๊ด์ฌ์ด ์์ต๋๋ค. ๋จ์ง fetchingํ ๋ฐ์ดํฐ๋ฅผ UI์ ๋ฐ์์ํค๋ ๊ฒ์๋ง ๊ด์ฌ์ด ๋ง์ต๋๋ค.
React์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์๋ useEffect์์ fetch ์์ฒญ์ ํ๋ ๋ฐฉ๋ฒ์ด๋ redux์ ๊ฐ์ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
์์ ๊ฐ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ isLoading, isError, isSuccess์ ๊ฐ์ ์ํ๋ฅผ ์ง์ ์ ์ํด์ผํ๊ณ ๋ง์ ๋ณด์ผ๋ฌ ํ๋ ์ดํธ ์ฝ๋๋ฅผ ์๋ฐํ๋ ๋จ์ ์ด ์กด์ฌํฉ๋๋ค.
react-query๋ ์ด๋ฅผ ํด๊ฒฐํฉ๋๋ค.
๋๋ค์์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ชจ๋ ๋น๋๊ธฐ ์ฝ๋๋ฅผ react-query๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ํ ๋จ๊ฒจ์ง๋ ์ ์ญ ์ํ๋ ๋งค์ฐ ์ ์ ๊ฒ ์ ๋๋ค. ์์ ๋ฅผ ํตํด์ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ํด ๊ด๋ฆฌ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ํ๋ค์ด ์์ต๋๋ค.
const globalState = {
projects, // server state
teams, // server state
tasks, // server state
users, // server state
themeMode, // client state
sidebarStatus, // client state
}
์ฌ๊ธฐ์ ์๋ฒ์ํ๋ฅผ react-query๋ก ์ฎ๊ธด๋ค๋ฉด ์ ์ญ ์ํ๋ ๋ง์ด ๊ฑฐ์ ๋จ์ง ์๊ฒ๋ฉ๋๋ค.
const globalState = {
themeMode,
sidebarStatus,
}
์ด๋ฅผ ํตํด ์ ์ ์๋ react-query์ ์ญํ ์ ๋ถ๋ช ํฉ๋๋ค.
์๋ฒ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ์ํด ํ์ํ๋ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ์ ๊ฑฐํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋จ ๋ช์ค์ ์ฝ๋๋ก ๋์ฒดํ๋ค.