Data Fetching, ๊ตฌ๋
๋ฑ์ side effect๋ ๋งค์ฐ ์กฐ์ฌ์ค๋ฝ๊ฒ ๋ค๋ค์ผ ํ๋ค.
๋ฆฌ์กํธ์์ side effect๋ ์ธ์ ์ด๋ป๊ฒ ๋ฐ์์์ผ์ผ ํ ๊น ?
const App = () => {
return <h1>Hello World</h1>
};
์์ ์ฝ๋์์ Hello Worldํํ์ JSX๋ฅผ ๋ธ๋ผ์ฐ์ ์ ๋ ๋๋ง ํ๋ค. ์ด ์ํฉ์์ side effect๋ฅผ ๋ฐ์์ํค๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น ??
๊ฐ์ฅ ๋จผ์ ๋ ์ฌ๋ฆด ์ ์๋ ์๊ฐ์ 'ํจ์์ return๋ฌธ ์์ ํ๊ณ ์ถ์ ๋์์ ๋ฃ์ด๋์'์ด๋ค.
const App = () => {
const doSideEffect = () => {
//do some side effect
};
doSideEffect();
return <h1>Hello World</h1>;
};
ํ์ง๋ง ์์ ๊ฐ์ด ๋๋๋ง ๋จ๊ณ์์ side effect๋ฅผ ๋ฐ์์ํค๋ฉด ๋ ๊ฐ์ง ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
1. side effect๊ฐ ๋ ๋๋ง์ blockingํ๋ค.
2. ๋งค ๋๋๋ง๋ง๋ค side effect๊ฐ ์ํ๋๋ค.
๋ฌด์จ๋ง์ธ๊ฐํ๋ฉด !
const App = () => {
const doSideEffect = () => {
//do some side effect
};
doSideEffect();
return <h1>Hello World</h1>;
};
๊ธฐ๋ณธ์ ์ผ๋ก ์ฝ๋๋ ์์์ ์๋๋ก ์์ฐจ์ ์ผ๋ก ์คํ๋๋ค. ๋ฐ๋ผ์ App ํจ์ ์ปดํฌ๋ํธ๋ doSideEffect()๋์์ด ๋๋ ๋๊น์ง JSX๋ฅผ ๋ฆฌํดํ๋ ์ฝ๋๋ก ๋์ด๊ฐ์ง ์๋๋ค. ์ปดํฌ๋ํธ๊ฐ JSX๋ฅผ returnํ๊ธฐ ์ ๊น์ง๋ UI๊ฐ ๋ธ๋ผ์ฐ์ ์์ ๋๋๋ง ๋์ง ์๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ตญ ์ฌ์ด๋ ์ดํํธ๊ฐ ๋๋๊ธฐ ์ ๊น์ง ๋ ๋๋ง์ ํ์ง ๋ชปํ๊ณ ๋ฉ์ถฐ์๊ฒ ๋๋ค.
์ฆ, ์ฌ์ฉ์๊ฐ UI๊ฐ ์ ๋ฐ์ดํธ๋๋ ๊ฒ์ ๋ณด๊ธฐ๊น์ง ์ค๋ ์๊ฐ์ด ์์๋๋ค๋ ๊ฒ์ด๋ค. ์ด๋ ๊ณง ์ฌ์ฉ์์๊ฒ ์ข์ง ๋ชปํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ค๋ ์๋ฏธ์ด๋ค.
ํน์ ํ side effect๋ค์ ๋งค๋ฒ ์คํ๋ ํ์๊ฐ ์์ ์๋ ์๋ค. ์๋ฅผ ๋ค์ด ์ธ์คํ๊ทธ๋จ์์ ํผ๋์ ๋ํ ์ ๋ณด๋ฅผ ๋ฐ์์ ๋ฆฌ์คํธ๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ๋ฉด์ด ์๋ค. ํผ๋๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด์๋ ์ต์ด์ ํผ๋ ๋ฐ์ดํฐ๋ค์ ๊ฐ์ ธ์ค๋(Data Fetching) side effect๊ฐ ํ์ํ๋ค.
์๊ฐ์ ํด๋ณด๋ฉด, ์ธ๋ถ์์ ๊ฐ์ ธ์ค๋ side effect๋ ๋งค ๋๋๋ง๋ง๋ค ์ํ๋ ํ์๋ ์๋ค.
const App = () => {
//data fetching side effect
getFeeds();
return FeedList;
};
ํผ๋๋ฆฌ์คํธ์์ ํน์ ํผ๋์ ์ข์์๋ฅผ ๋๋ฅด๋ฉด ํํธ ์๊น์ด ๋ณ๊ฒฝ๋๋ค. ์์์ ๋ณ๊ฒฝํ๋ ค๋ฉด ์ปดํฌ๋ํธ์์ ๋ฆฌ๋๋๋ง์ ๋ฐ์์์ผ์ผ ํ๋๋ฐ, ๋ฆฌ๋๋๋ง์ด ๋๋ค๋ ๊ฒ์ ํจ์ ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ํ๋ฒ ํธ์ถํ๋ค๋ ๋ป์ด๋ค.
(๋ฆฌ์กํธ๋ ์ปดํฌ๋ํธ์ state๋ props๊ฐ ๋ณํ๋ฉด ์๋์ผ๋ก ํด๋น ํจ์ ์ปดํฌ๋ํธ๋ฅผ ๋ค์ ํธ์ถํ๋ฉด์ ๋ฆฌ๋๋๋ง์ ์ํํด์ค๋ค.)
์ฆ, App์ด๋ผ๋ ํจ์๊ฐ ๋ค์ ํธ์ถ๋๊ณ ๊ทธ๋ ๋ค๋ฉด ๋ค์ ํจ์ ๋ด๋ถ์ ์ฝ๋๋ฅผ ์์์ ์๋๋ก ์์ฐจ์ ์ผ๋ก ์คํ์ํจ๋ค.
๊ทธ ๋ง์ ๋ค์ ํ๋ฒ getFeeds() side effect๋ฅผ ๋ฐ์์ํจ๋ค๋ ์๋ฏธ์ด๋ค.
์์ UI ์ ๋ฐ์ดํธ ๋ฐ์ ์ ๋ง๋ค ๋งค๋ฒ ๋ชจ๋ ํผ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค ๊ฐ์ ธ์จ๋ค๋ฉด ๋ถํ์ํ ๋์์ ๊ณ์ ์ํํ๊ธฐ์ ๋นํจ์จ์ ์ด๋ค.
React์์ side effect๋
1. ๋๋๋ง์ blocking ํ์ง ์๊ธฐ ์ํด์ ๋๋๋ง์ด ๋ชจ๋ ์๋ฃ๋๊ณ ๋ ํ ์คํํ ์ ์์ด์ผ ํ๋ค.
2. ๋งค ๋๋๋ง๋ง๋ค ์คํ๋๋ ๊ฒ์ด ์๋๋ผ ๋ด๊ฐ ์ํ ๋๋ง ์กฐ๊ฑด๋ถ๋ก ์คํํ ์ ์์ด์ผ ํ๋ค.
์ ๋๊ฐ์ง ์กฐ๊ฑด์ ์ถฉ์กฑ์ํค๋ฉด์ ๋ฐ์์ํค๋ ๊ฒ์ด ์ข๋ค.
์ด ๋๊ฐ์ง๋ฅผ ์ถฉ์กฑ์ํค๋ฉด์ side effect๋ฅผ ๋ฐ์์ํฌ ์ ์๊ฒ ๋์์ฃผ๋ ๊ฒ์ด useEffect ๋ผ๋ hook์ด๋ค.
useEffect๋ ๋ฆฌ์กํธ์์ side effect๋ฅผ ํธ๋ฆฌํ๊ณ ์์ ํ๊ฒ ๋ฐ์์ํฌ ์ ์๊ฒ ๋์์ฃผ๋ hook์ด๋ค.
์ฌ์ฉ๋ฒ์,
useEffect(์ฝ๋ฐฑํจ์);
useEffect๋ ํจ์์ด๊ณ , ๋งค๊ฐ๋ณ์๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ๊ฐ์ง๋ค. ์ฐ๋ฆฌ๋ useEffect์ ์ธ์๋ก ์ ๋ฌํ๋ ์ฝ๋ฐฑ ํจ์์์ ํน์ ํ side effect๋ฅผ ์ํ์ํฌ ์ ์๋ค.
const App = () => {
doSideEffect();
return <h1>Hello World</h1>
};
์ ์ฝ๋๋ useEffect์์ด side effect๋ฅผ ๋ฐ์์ํค๋ ์ฝ๋์ด๋ค. ์ฌ๊ธฐ์๋ side effect๋ฅผ ๋๋๋ง ์ ์ ๋ฐ์์ํค๊ณ ์๋ค. ์ด๋ฌํ ์ฝ๋๋ ๋ ๋๋ง์ blockingํ๊ธฐ์ ์ข์ง ์๊ธฐ์ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ useEffect๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
import { useEffect } from 'react';
const App = () => {
// ์ฝ๋ ์๋ต
useEffect(doSideEffect);
return <h1>Hello, Wecoder</h1>;
};
side effect๋ฅผ ๋ฐ์์ํค๋ ํจ์๋ฅผ ๋ฐ๋ก ํ์ฒ ํ๋ ๊ฒ์ด ์๋๋ผ useEffect์ ์ธ์๋ก ์ ๋ฌํ๋ค.
์์ ๊ฐ์ด useEffect์ ์ธ์๋ก ์ ๋ฌ๋ ์ฝ๋ฐฑ ํจ์๋ ๊ณง๋ฐ๋ก ํธ์ถ๋๋ ๊ฒ์ด ์๋๋ผ ๋ชจ๋ ๋๋๋ง์ด ์๋ฃ๋ ํ์ ํธ์ถ๋๋ค.
์ฆ, ๋๋๋ง์ blocking ํ์ง ์๊ณ side effect๋ฅผ ๋ฐ์์ํฌ ์ ์๊ฒ ๋๋ ๊ฒ์ด๋ค.
useEffect๋ฅผ ํตํด์ ๋๋๋ง์ด ๋ชจ๋ ์๋ฃ๋๊ณ ๋ ํ side effect๋ฅผ ์คํํ๋ค๋ ์๊ตฌ์ฌํญ์ ์ถฉ์กฑ๋์์ง๋ง ์์ง๋ ๋งค ๋๋๋ง๋ง๋ค side effect๊ฐ ์คํ๋๋ค๋ ์ฌ์ค์ ๋ณํจ์ด ์๋ค.
ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑํ ๋๋ง ๋ฐ์์ํค๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ผ๊น ?
useEffect๋ ์ฝ๋ฐฑ ํจ์ ์ธ์ ์์กด์ฑ ๋ฐฐ์ด์ด๋ผ๋ ๋๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง๋ค.
์์กด์ฑ ๋ฐฐ์ด์ ๋ฐฐ์ด์ ํํ์ด๋ค. ์ด ๋ฐฐ์ด์ด side effect์ ๋ฐ์ ์ฌ๋ถ๋ฅด ๊ฒฐ์ ์ง๋ ์กฐ๊ฑด์ด๋ค.
useEffect(์ฝ๋ฐฑ ํจ์, ์์กด์ฑ ๋ฐฐ์ด)
useEffect์ ๋์ ๋ฐฉ์
์ฒซ ๋ฒ์งธ ๋๋๋ง ์ดํ์๋ ๋ฌด์กฐ๊ฑด useEffect์ ์ ๋ฌ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ๊ณ ๋ค์ ๋๋๋ง๋ถํฐ๋ ์๋์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋์ํ๋ค.
์ฆ, useEffect์์ ์ฒซ ๋ฒ์งธ ์ธ์์ธ ์ฝ๋ฐฑ ํจ์๋ ์คํ์ํฌ ๋์์ ๊ฒฐ์ ํ๊ณ ๋ ๋ฒ์ฉจ ์ธ์์ธ ์์กด์ฑ ๋ฐฐ์ด์ ์คํ์ํฌ ํ์ด๋ฐ์ ๊ฒฐ์ ์ง๋๋ค๊ณ ํ ์ ์๋ค.
์์ ๊ทธ๋ฆผ์ useEffect์ React Component๊ฐ ๋ ๋๋ง ๋๋ ๊ณผ์ ์ ํจ๊ผ ๋์ํ ํ ๋ค์ด์ด๊ทธ๋จ์ด๋ค.
ํจ์ ์ปดํฌ๋ํธ์ ๋ ๋๋ง๊ณผ useEffect๊ฐ ๋ฐ์ํ๋ ๊ณผ์ ์ ํ์ด์ ์ค๋ช
ํ๋ฉด,
1. ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋๋ค. (์ต์ด๋ก ์งํ๋๋ ๋ ๋๋ง์ ๋ธ๋ผ์ฐ์ ์ ์ฒ์์ผ๋ก ์ด ์ปดํฌ๋ํธ๊ฐ ๋ณด์๋ค๋ ์๋ฏธ๋ก mount๋ผ๊ณ ํํํ๋ค.)
2. useEffect ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋๊ฒจ์ค ์ฝ๋ฐฑ ํจ์๊ฐ ํธ์ถ๋๋ค (side effect)
3. ์ปดํฌ๋ํธ์ state ๋๋ props๊ฐ ๋ณ๊ฒฝ๋์์ ๊ฒฝ์ฐ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ๋ค. (update)
4. useEffect๋ ๋ ๋ฒ์งธ ์ธ์์ ๋ค์ด์๋ ์์กด์ฑ ๋ฐฐ์ด์ ํ์ธํ๋ค.
- ๋ง์ฝ ์์กด์ฑ ๋ฐฐ์ด์ด ์ ๋ฌ๋์ง ์์๊ฑฐ๋, ์์กด์ฑ ๋ฐฐ์ด ๋ด๋ถ์ ๊ฐ ์ค ์ด์ ๋ ๋๋ง๊ณผ ๋น๊ตํ์ ๋ ๋ณ๊ฒฝ๋๊ฐ์ด ํ๋๋ผ๋ ์๋ค๋ฉด ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋๊ฒจ์ค ์ฝ๋ฐฑ ํจ์๊ฐ ํธ์ถ๋๋ค. (side effect)
- ์์กด์ฑ ๋ฐฐ์ด ๋ด๋ถ์ ๊ฐ ์ค ์ด์ ๋ ๋๋ง๊ณผ ๋น๊ตํ์ ๋ ๋ณ๊ฒฝ๋ ๊ฐ์ด ์๋ค๋ฉด ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ์ง ์๋๋ค.
- state ๋๋ props๊ฐ ๋ณ๊ฒฝ๋๋ค๋ฉด 3 - 4 ๊ณผ์ ๋ฐ๋ณต
5. ์ปดํฌ๋ํธ๊ฐ ๋ ์ด์ ํ์ ์์ด์ง๋ฉด ํ๋ฉด์์ ์ฌ๋ผ์ง๋ค. (์ปดํฌ๋ํธ๊ฐ ๋ธ๋ผ์ฐ์ ์ ํ๋ฉด์์ ์ฌ๋ผ์ก๋ค๋ ์๋ฏธ๋ก unmount๋ผ๊ณ ํํํ๋ค.)
๋ถํ์ํ๊ฒ ๊ณ์ํด์ side effect๊ฐ ๋จ์์์ด์ ๋นํจ์จ์ ์ผ๋ก ์๋ํ ์ ์๊ณ , ํ๋ก๊ทธ๋จ์ ๋์์ด ์๋ํ ๋๋ก ๋์ง ์์ ์ ์๊ธฐ ๋๋ฌธ์ ์ง์์ ์ผ๋ก ๋จ์์๊ฒ๋๋ side effect๋ฅผ ๋ฐ๋์ clean upํด์ค์ผ ํ๋ค.
useEffect(() => {
const cntTime = () => {
console.log('100ms๊ฐ ์ง๋จ');
};
setInterval)cntTime, 100);
}, []);
์์ side effect๋ claen up์ด ํ์ํ๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉด setInterval ํจ์๋ฅผ ์ด์ฉํด์ 100ms๋ง๋ค cntTime ํจ์๊ฐ ํธ์ถ๋๋ค.
useEffect์ ์์กด์ฑ ๋ฐฐ์ด์ ๋น ๋ฐฐ์ด์ด ์ ๋ฌ๋์์ผ๋ฏ๋ก ์ฒซ ๋ฒ์งธ ๋๋๋ง ์ดํ์ side effect๊ฐ ์คํธ๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด side effect๋ฅผ clean up ํด์ฃผ์ง ์๋๋ค๋ฉด ์ปดํฌ๋ํธ๊ฐ unmount ๋๋ ๊ฒฝ์ฐ ๋ฑ setInterval์ ํตํ ๊ตฌ๋
์ด ํ์ ์์ด์ง ์ํฉ์์๋ ๊ณ์ํด์ ์ฝ์์ด ์ถ๋ ฅ์ด ๋๋ค.
๋ ๋ค๋ฅธ ์๋ฅผ ๋ค์ด๋ณด๋ฉด,
useEffect(() => {
const button = document.getElementById('consoleButton'); // 1
const printConsole = () => {
console.log('button clicked');
}; // 2
button.addEventListener('click', printConsole); // 3
});
useEffect์ ์์กด์ฑ ๋ฐฐ์ด์ ์ ๋ฌํ์ง ์์์ ๋ side effect๊ฐ ๋งค ๋ ๋๋ง๋ง๋ค ์คํ๋๋ค.
์์ ์ฝ๋๋ ์๋์ ์์๋ก ๋์์ ํ๊ณ ์๋ค.
์ด side effect๋ ๋งค ๋ ๋๋ง๋ง๋ค ์คํ๋๊ธฐ ๋๋ฌธ์ ๋ ๋๋ง์ด ๋ ๋๋ง๋ค button์ eventListener๊ฐ ์ถ๊ฐ๋๋ค. ์ฆ eventListener๊ฐ ๊ณ์ํด์ ์ค์ฒฉ๋๊ณ ์๋ค๋ ๋ป์ด๋ค.
๋ฐ๋ผ์, ์ฒซ ๋ ๋๋ง ์ดํ์๋ ๋ฒํผ์ ๋๋ฅด๋ฉด ์ฝ์์ด ํ๋ฒ๋ง ์ถ๋ ฅ๋์ง๋ง, ๋ ๋ฒ์งธ ๋ ๋๋ง์ด ๋๋ฉด ์ด๋ฒคํธ๋ฆฌ์ค๋๊ฐ ํ๋ฒ ๋ ์ถ๊ฐ๋๊ธฐ ๋๋ฌธ์ ๋ ๋๋ง์ด ๋ ๋๋ง๋ค ์ฝ์ ์ถ๋ ฅ ํ์๊ฐ ๋์ด๋๊ฒ ๋๋ค.
๊ทธ๋์ clean up์ด ํ์ํ ๊ฒ์ด๋ค.
useEffect๋ side effect๋ฅผ clean up ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํด์ค๋ค.
useEffect์์ side effect๋ฅผ clean up ํ๊ธฐ ์ํด์๋ useEffect์ ์ ๋ฌํ ์ฝ๋ฐฑ ํจ์์์ claen up์ ํ๋ ํจ์๋ฅผ ๋ฆฌํดํ๋ฉด ๋๋ค.
useEffect(() => {
const button = document.getElementById('consoleButton');
const printConsole = () => {
console.log('button clicked');
};
button.addEventListener('click', printConsole);
// side effect๋ฅผ clean up ํ๊ธฐ ์ํ ํจ์๋ฅผ ์ ์ธํ๋ค.
const removeEventListener = () => {
button.removeEventListener('click', printConsole);
};
// clean up ํจ์๋ฅผ return ํ๋ค.
return removeEventListener;
});
์์ ์ฝ๋๋ก ๋ณด๋ฉด side effect๋ฅผ ์์ ๊ธฐ ์ํ ํจ์๋ฅผ ๋ง๋ค๊ณ , ๊ทธ ํจ์๋ฅผ ๋ฆฌํดํด์ฃผ์๋ค.
useEffect๋ clean up ํจ์๋ฅผ ๋ ๊ฐ์ง ๊ฒฝ์ฐ์ ํธ์ถํ๋ค.
1. ๋ค์ side effect๋ฅผ ๋ฐ์์ํค๊ธฐ ์
2. ์ปดํฌ๋ํธ๊ฐ unmount ๋ ๋