๋ฆฌ์กํธ Hook์ ์ปดํฌ๋ํธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌ(State)ํ๊ณ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋ ์ํธ์์ฉ(Effect)์ ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ์ด๋ค.
์ปดํฌ๋ํธ๋ ํจ์ํ ์ปดํฌ๋ํธ์ ํด๋์คํ ์ปดํฌ๋ํธ ๋๊ฐ์ง๊ฐ ์์ง๋ง, ๊ธฐ์กด์๋ ํจ์ํ์ ์ํ ๊ด๋ฆฌ์กฐ์ฐจ ํ ์๊ฐ ์๋ ๊ฐ๋จํ ์ปดํฌ๋ํธ์ ๋ถ๊ณผํ๋ค๊ณ ํ๋ค.
๋๋ฌธ์ ์ํ ๊ด๋ฆฌ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฑ ๋ค๋ฅธ ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค์ ๊ฐ์ง ํด๋์คํ ์ปดํฌ๋ํธ๋ฅผ ์ฃผ๋ก ์ฌ์ฉํ๋๋ฐ, ์ด ๊ธฐ๋ฅ๋ค์ ํจ์ํ ์ปดํฌ๋ํธ์์๋ ์ฌ์ฉํ ์ ์๋๋ก React 16.8 ๋ฒ์ ์ ์๋ก ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ด Hook์ด๋ค.
์ด์ ์ ํจ์ํ ์ปดํฌ๋ํธ์์ state ๋ณ์๋ฅผ ๋ณ๊ฒฝํ๊ธฐ์ํด ์ฌ์ฉํ useState๊ฐ ๋ฐ๋ก ์ํ ๊ด๋ฆฌ ํ , State Hook์ด๋ค.
Hook์ ๋ฆฌ์กํธ์ ํจ์ ๋ด์์๋ง ์ฌ์ฉํด์ผ ํ๋ค.
์ ์ด์ Hook์ด๋ผ๋ ๊ธฐ๋ฅ์ด ํจ์ํ ์ปดํฌ๋ํธ์์๋ ํ์ง๋ชปํ๋ ์ฌ๋ฌ๊ฐ์ง ๊ธฐ๋ฅ์ ๋ค๋ฃฐ ์ ์๋๋ก ๋์ ๋ ๊ฒ์ด๋ ๋น์ฐํ๋ค.
Hook์ ํธ์ถ์ ์ต์์ ๋ ๋ฒจ์์๋ง ๊ฐ๋ฅํ๋ค
Hook์ ํจ์์ ์ต์์ ๋ ๋ฒจ, ํจ์์ '์ ์ญ'์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. ํจ์ ๋ด์ if๋ฌธ, for๋ฌธ, ์ฝ๋ฐฑํจ์ ๋ฑ์์๋ ์ฌ์ฉํ ์ ์์!
๊ทธ๋ฆฌ๊ณ ์ ์์ฌํญ์ด๋ผ๊ธฐ์ ๋ญํ์ง๋ง ๋ฆฌ์กํธ์ Hook์ ์ด๋ฆ์์ ๋ค use๊ฐ ๋ถ๋๋ค. useState, useEffect, useRef ๋ฑ๋ฑ.. ์์ผ๋ก ์ดํด๋ณผ ํ ๋ค์ ๋ชจ๋ ์ด๋ ๊ฒ ๋ค์ด๋ฐ ๋์ด์๋ค๊ณ ์์๋์!
useEffect๋ side effect์ ์ฒ๋ฆฌํ๊ธฐ ์ํ Hook์ด๋ค.
useEffect๋ฅผ ์ ์ฌ์ฉํ๋์ง๋ฅผ ์ดํดํ๊ธฐ ์ํด์๋ ์ด side effect ๋ผ๋ ๊ฒ์ ์ดํดํด์ผ ํ๋ ์ข ์ดํด๋ณด์.
์ง์ญํ์๋ฉด '๋ถ์์ฉ'์ผ๋ก ์ฐ๋ฆฌ๊ฐ ํํ ์๋ ๊ทธ ๋ถ์์ฉ์ด ๋ ์ค๋ฅด๋๋ฐ ์ปดํจํฐ ๊ณตํ์์๋ ๊ทธ๋ฐ ์๋ฏธ๋ ์๋๊ณ , ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์ ์ฌ์ฉํ๋ ์ฉ์ด๋ก '๋ถ์ ํจ๊ณผ'๋ผ๋ ์๋ฏธ๋ผ๊ณ ํ๋ค.
์ฌ๊ธฐ์ ๋งํ๋ ๋ถ์ ํจ๊ณผ๋ ํจ์๊ฐ ์คํ๋ ๋ ์ธ๋ถ์ ์กด์ฌํ๋ ๊ฐ ๋๋ ์ด๋ค ์ํ๋ฅผ ๋ณ๊ฒฝ์ํค๊ฑฐ๋ ๊ฐ์ ธ๋ค ์ฐ๋ ํจ๊ณผ, ์ฆ ํจ์ ๋ด๋ถ์ ๋์์ด ํด๋น ํจ์ ๋ฐ์ ์ธ๊ณ์๋ ๋ญ๊ฐ ์ํธ์์ฉ์ ํ๋ ๊ฒ์ ๋งํ๋ค.
side effect์ ์๋ฅผ ๋ค์๋ฉด ๋ณดํต ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ๋ฑ์ด ์๋ค.
Props์ State ํฌ์คํ ์์ ์ ๊น ์ธ๊ธํ ๊ฒ ์ค์ '์์ ํจ์(Pure function)' ๋ผ๋ ๊ฒ์ด ์์๊ณ ๋ค์๊ณผ ๊ฐ์ React์ ์ฒ ํ์ ์๊ฐํ์๋ค.
๋ชจ๋ React ์ปดํฌ๋ํธ๋ props์ ๊ด๋ จํ ๋์์ ํ ๋ ์์ ํจ์์ฒ๋ผ ๋์ํด์ผํ๋ค.
๋๊ฐ์ ๋ด๋น๋ค์ ๋ณดํต ์์ ํจ์(Pure function)๋ฅผ '๋์ผํ ์ ๋ ฅ์ ๋ํ ํจ์์ ๋ฆฌํด๊ฐ์ด ํญ์ ๋์ผํ ํจ์' ์ ๋๋ก ์๊ณ ์๋ค.
๋ง๋ ๋ง์ด์ง๋ง ์์ ํจ์๊ฐ ๋๊ธฐ ์ํ ์กฐ๊ฑด์ ํ๊ฐ์ง ๋ ์๋ค.
ํจ์์ side effect๊ฐ ์๋ค
'์ด๋ ํ ํจ์์ ๋ด๋ถ ๋์์ด ํด๋น ํจ์ ๋ฐ์๋ ๋ฌด์ธ๊ฐ ์ํฅ์ ์ค๋ค๋ฉด, ํน์ ์ํธ์์ฉ์ ํ๋ค๋ฉด ํด๋น ํจ์๋ side effect๊ฐ ์๋ค' ๋ผ๊ณ ๋งํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฆฌ์กํธ์ ์ปดํฌ๋ํธ๋ ์ด๋ฌํ side effect๊ฐ ์๋ ์์ ํจ์์ ํํ๋ฅผ ์งํฅํด์ผ ํ๋ค๊ณ ๋งํ๊ณ ์๋ ๊ฒ์ด๋ค. ์ ๊ทธ๋ด๊น?
์ปดํฌ๋ํธ์์ setInterval์ ์ฌ์ฉํ๋ ์๋ฅผ ํ๊ฐ์ง ๋ค์ด๋ณด๊ฒ ๋ค.
function App() {
const [count, setCount] = useState(0);
setInterval(() => {
setCount(count+1);
}, 1000);
return (
<div className="App">
{count}
</div>
);
}
์คํํ๋ฉด ํ๋ฉด์ 0๋ถํฐ ์์ํด์ 1์ด์ 1์ฉ ์ฆ๊ฐํ๋ ๋ชจ์ต์ด ๋์ค๋ ๊ฐ๋จํ ์ปดํฌ๋ํธ์ด๋ค.
๊ทธ๋ฐ๋ฐ 10์ด ๋์๋์ฏค๋ถํฐ ๋ญ๊ฐ ์ด์ํ ๋ชจ์ต์ ๋ณผ ์ ์์ ๊ฒ์ด๋ค. ์๊ฐ ๋ฑ๋ฑ ์ฌ๋ผ๊ฐ๋๊ฒ ์๋๋ผ ๋ค๋ฅธ ์ซ์๋ค์ด ์๊ฐ์ ์ผ๋ก ๊ฒน์ณ์ ๋ณด์ด๋๋ฏํ ๋ชจ์ต์ด ๋ณด์ธ๋ค.
์ซ์๊ฐ ์ปค์ง์๋ก ์ด ํ์์ ์ ์ ๋ ์ฌํด์ ธ 30์ ๋๊ฐ ๋์ด๊ฐ๋ฉด ์นด์ดํธ๊ฐ ์ ์ ์ ๋ชป์ฐจ๋ฆฐ๋ค.
์ด ํ์์ ์์ธ์ setInterval์ด๋ค.
setInterval์ ์ ํด์ง ์๊ฐ ๊ฐ๊ฒฉ๋ง๋ค ์ ํด์ค ๋์์ ๋ฐ๋ณต ์คํํ๋ ์ธ๋ถ ๋ฉ์๋. ์ฆ ์ธ๋ถ์ ์น api๋ก, ์ด ์ปดํฌ๋ํธ ๋ด๋ถ ํ์์ธ ๋ค๋ฅธ ์ ๋ค๊ณผ๋ ๊ทผ๋ณธ๋ถํฐ๊ฐ ๋ค๋ฅธ ๋์ด๋ค. ์ด๋ฐ ์ธ๋ถ api๋ฅผ ๊ฐ์ ธ๋ค ์ฐ๋๊ฒ์ฒ๋ผ ํจ์ ๋ด๋ถ์ ๋ก์ง๊ณผ ๋ณ๊ฐ๋ก ์ธ๋ถ๋ก๋ถํฐ ์ํฅ์ ๋ฐ๊ฑฐ๋ ์ธ๋ถ์ ์ํฅ์ ์ฃผ๊ฑฐ๋ ํ๋ ์ ๋ค์ด side effect์ด๋ค.
์์ ์ปดํฌ๋ํธ์์ count๊ฐ ์ฆ๊ฐํ์ฌ App ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋์ด๋ setInterval์ ์ด ์ปดํฌ๋ํธ ๋ก์ง๊ณผ๋ ๋ณ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด์ setInterval์ ๋์์ด ๊ณ์ ์ ์ง๋๋ค.
๊ทธ๋ฐ๋ฐ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋์ด ๋ก์ง์ด ๋ค์ ์คํ๋๋ฉด ๊ฑฐ๊ธฐ์ ์๋ก์ด setInterval์ด ์ถ๊ฐ๋๋ ๊ฒ์ด๋ค. ์ด ๊ณผ์ ์ด ๋ฐ๋ณต๋์ด ์ ์ ๋์ ๋๋ค๋ณด๋ ๋์ํ๋ setInterval์ด ๋ง์์ ธ์ ์นด์ดํธ๊ฐ ์ ์ ๋ง์ด ๊ฐ๋ฒ๋ฆฌ๋ ๊ฒ์ด๋ค.
์ฆ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋จ์ ๋ฐ๋ผ side effect๊ฐ ์ค์ฒฉ๋์ด ๋ํ๋๋ ์ด์ ํ์์ธ ๊ฒ์ด๋ค.
์ด ์์๋ฅผ ํตํด ๊ฒฐ๊ณผ์ ์ผ๋ก ๋งํ๊ณ ์ถ์ ๊ฒ์ ์ด๋ฌํ side effect๋ ์ค๊ณ์๊ฐ ์์ํ์ง ๋ชปํ ํ์์ ๋ฐ์์ํฌ ํ๋ฅ ์ด ๋๋ค๋ผ๋๊ฒ. ์ฆ ๋ฒ๊ทธ๋ฅผ ์ ๋ฐํ๊ธฐ๊ฐ ์ฝ๋ค๋ ๊ฒ์ด๋ค.
side effect๋ ์ปดํฌ๋ํธ์ ๊ฒฐ๊ณผ๋ฅผ ์์ธกํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ ๋ค
์ปดํฌ๋ํธ ์์ ์๋ side effect๊ฐ ์๋ ์ ๋ค์ ์ปดํฌ๋ํธ๋ฅผ ์ธ์ ๋ ๋๊ฐ์ด ๋์ํ๋ ์์ ํจ์์ฒ๋ผ ๋์ํ๊ฒ ํ๋ค. ๊ทผ๋ฐ side effect๋ ์ปดํฌ๋ํธ ์์์ ์ธ๋ถ์ ์ํฅ์ ์ฃผ๊ณ , ์ธ๋ถ์ ๊ฒ์ ๊ฐ์ ธ๋ค ์ฐ๋ ๋ฑ '์ธ๋ถ ์ธ๊ณ'์ ์ํธ์์ฉํ๊ธฐ ๋๋ฌธ์ ์ด๋ค ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ง ์์ธกํ๊ธฐ ์ด๋ ต๊ฒ ํ๋ค.
๊ทธ๋์ side effect๊ฐ ์๋ ์ปดํฌ๋ํธ๋ ์์ ํจ์์ฒ๋ผ ํ๊ฒฐ๊ฐ์ ์ ์๊ฒ ๋๋ ๊ฒ์ด๋ค.
(์ด๋ฐ ๊ด์ ์์๋ณด๋ฉด side effect๋ฅผ ๊ทธ๋ฅ '๋ถ์์ฉ'์ด๋ผ๊ณ ๋ด๋ ์๊ด์์๊ฑฐ ๊ฐ๊ธฐ๋ ํ๋ค.. ๐ซ )
๋ชจ๋ React ์ปดํฌ๋ํธ๋ props์ ๊ด๋ จํ ๋์์ ํ ๋ ์์ ํจ์์ฒ๋ผ ๋์ํด์ผํ๋ค.
๊ทธ๋ ๊ธฐ๋๋ฌธ์ ๋ฆฌ์กํธ๋ ์ด๋ฐ ์ฒ ํ์ ๋ด์ธ์ฐ๋๊ฒ ์๋๊น ํ๋ ์๊ฐ์ด ๋ ๋ค. ์ปดํฌ๋ํธ๋ค์ด ์์ ํจ์์ฒ๋ผ ๋์ํด์ผ ๊น-๋ํ๋๊น..!
ํ์ง๋ง ๊ทธ๋ ๋ค๊ณ ๋ชจ๋ ์ปดํฌ๋ํธ์ side effect๋ฅผ ์ฐ์ง ์์ ์๋ ์์๊ฒ์ด๋ค. ์คํ๋ ค side effect๋ฅผ ์จ์ผํ๋ ์ํฉ์ด ํจ์ฌ ๋ง์๊ฒ์ด๋ค.
์ค์ ๋ก ์์ฃผ ๋จ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ธํ ์ฌ์ค์ ๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ๋ฐฉ์์ผ๋ก๋ side effect์ ์์กดํ๋ค๊ณ ํ๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ฆฌ์กํธ์์ side effect๋ฅผ ์ฒ๋ฆฌํ๋ ๋ณ๋์ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๊ธฐ ์ํด ๋์จ Hook์ด ๋ฐ๋ก useEffect์ธ ๊ฒ์ด๋ค.
๋ฆฌ์กํธ์์ ์ปดํฌ๋ํธ๋ ๋ณดํต ์์๋ก ๋ฆฌ๋ ๋๋ง๋๋๊ฒ ์ผ๋ฐ์ ์ด๊ธฐ ๋๋ฌธ์ ์์์์ฒ๋ผ side effect๋ฅผ ๋ค๋ฅธ์ ๋ค์ฒ๋ผ ํ๋ฒํ๊ฒ ๋ฐ์๋๋ค๊ฐ ์ด๋ค ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ง ๋ชจ๋ฅธ๋ค. useEffect๋ side effect๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ํ์ด๋ฐ์๋ง ์์๋ฑํ๊ฒ ์ํ๋ ์ ์๋๋ก ํ์ฌ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ค๋ค.
useEffect์ ๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ๋ฐฉ๋ฒ์ ์ด๋ ๋ค.
import { useEffect } from 'react';
useEffect(Callback, Deps?)
(์ผ๋จ ๋น์ฐํ useState์ ๋๊ฐ์ด react์์ ์ํฌํธ๋ฅผ ํด์ค๋ค)
Callback ๋ถ๋ถ์ ์ฝ๋ฐฑํจ์์ ์ํ๋ ์์ ๋ง๋ค ์คํ์ํฌ ๋ก์ง, ์ฆ side effect๋ฅผ ์ง์ ํด์ฃผ๋ฉด ๋๋ค.
Deps๋ Callback์ ์คํ์ํค๋ ๊ธฐ์ค์ด ๋๋ ๋ณ์๋ค์ ์ ์ฅํ๋ ๋ฐฐ์ด์ด๋ค. ๋ค์ ?๊ฐ ๋ถ์๊ฑด ์ด ์ธ์๋ ํ์๊ฐ์ ์๋๋ผ๋ ํ๊ธฐ๋ฒ์ด๋ค. ์๋ตํ์ฌ Callback๋ง ์ง์ ํ ์๋ ์๊ณ ์ํ๋ state ๋ณ์๋ค์ ์ง์ ํ๊ฑฐ๋ ๋น ๋ฐฐ์ด๋ก ํ์ฌ ์ธ์๋ก ์ง์ ํ ์๋ ์๋ค.
Deps๊ฐ ์๋๋ ์๋๋, ์๋ค๋ฉด Deps ๋ฐฐ์ด์ด ๋น ๋ฐฐ์ด์ด๋ ์๋๋์ ๋ฐ๋ผ Callback์ด ์ด๋ค ํ์ด๋ฐ์ ์คํ๋๋์ง๊ฐ ์ ํด์ง๋ค. ๊ฐ๊ฐ์ ๊ฒฝ์ฐ์ ๋ํ ์์๋ฅผ ๋ณด๋ฉฐ ์์๋ณด์.
Deps ์ธ์๋ฅผ ์์ ์๋ฃ์ด์ฃผ๋ฉด useEffect์ Callback์ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ ๋๋ง๋ค ์คํ๋๋ค.
function App() {
const [render, setRender] = useState(true);
console.log(render);
useEffect(() => {
console.log("์นด์ดํธ ์์!");
})
const handleClick = () => {
setRender(curr => !curr);
}
return (
<div className="App">
<button onClick={handleClick}>๋ฆฌ๋ ๋๋ง</button>
</div>
);
}
๋ฆฌ๋ ๋๋ง ๋ฒํผ์ ๋๋ฌ render ๋ณ์๋ฅผ ๋ฐ์ ์์ผ์ค๋๋ง๋ค ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋๊ณ ๊ทธ๋๋ง๋ค useEffect์ Callback์ด ์คํ๋์ด ์ฝ์์ฐฝ์ "์นด์ดํธ ์์!"์ด ๋จ๋๊ฒ์ ๋ณผ ์ ์๋ค.
Deps์ ๋น ๋ฐฐ์ด์ ๋ฃ์ผ๋ฉด useEffect์ Callback์ ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ๋ ๋๋ง ๋ ๋๋ง ๋ฑ 1๋ฒ ์คํ๋๋ค.
์๊น์ setInterval์ useEffect๋ฅผ ์ฌ์ฉํด ์ฒ๋ฆฌํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
setInterval(() => {
setCount(curr => curr+1);
}, 1000);
}, [])
return (
<div className="App">
{count}
</div>
);
}
Deps๊ฐ ๋น ๋ฐฐ์ด์ด๋ ์ปดํฌ๋ํธ ์ต์ด ๋ ๋๋ง์์๋ง ๋ฑ ํ๋ฒ setInterval์ด ์คํ๋๋ฏ๋ก count๊ฐ ๋ณํจ์ ๋ฐ๋ผ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋์ด๋ setInterval์ด ์ค์ฒฉ๋๋์ผ ์์ด ์ ์์ ์ผ๋ก ์นด์ดํธ๊ฐ ์ฌ๋ผ๊ฐ๊ฒ ๋๋ค.
๊ทผ๋ฐ ์นด์ดํธ๊ฐ 2์ฉ ์ฌ๋ผ๊ฐ. ๋๋ ์์ด๋ฐ๊ฑด์ง ๋ชฐ๋ผ์ ๋ต๋ตํ๋๋ฐ.. ์ฐพ์๋ณด๋ index.js์ React.StrictMode ๋๋ฌธ์ด๋ผ๊ณ ํ๋ค..! ์๋ฅผ ์์ ๋ฉด ์ ์์ ์ผ๋ก 1์ฉ ์ฆ๊ฐํจ
์ด๊ฒ์ ๋ํด ์ ๋ฆฌํด์ค ๊ณ ๋ง์ด ๊ณ ์ธ๋ฌผ๋ถ๋ค์ด ๋ง์ด ๊ณ์ ์ ๋คํํ ์์ธ์ ์ ์ ์์๋ค. ๐โโ๏ธ
์์ธํ ๋ด์ฉ์ ์ด ๊ธ์ ์ฐธ๊ณ ํด์ฃผ์ญ์ ฉ
์ ์ฝ๋์์ setInterval์ setCount๋ฅผ ์์์์ฒ๋ผ setCount(count+1)๋ก ํ๋ค๋ฉด ์ต์ด ๋ ๋๋ง ์ 0์ด ๋์ค๊ณ 1์ด๋ค 1์ด ๋์๋ค๊ฐ ๊ทธ์ํ์์ ๋ฉ์ถ๋ค.
์ด๋ ์ค์ ๋ก setInterval์ด ๋ฉ์ถ๊ฒ ์๋๊ณ count๊ฐ 1๊น์ง๋ง ์ฆ๊ฐํ๊ณ ๊ณ์ ๋ค์ 1์ด ๋๊ธฐ๋๋ฌธ์ธ๋ฐ ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ํด๋ก์ ๊ฐ๋ ์ ์ฐพ์๋ณด๋ฉด ์ ์ ์์ ๊ฒ์ด๋ค.
๊ฒฐ๋ก ๋ง ๋งํ์๋ฉด useEffect์ ์ฝ๋ฐฑํจ์๊ฐ ์ ์ธ๋ ์์ ์ count๊ฐ์ด 0์ด์์ผ๋ฏ๋ก ๊ทธ ์ฝ๋ฐฑํจ์ ๋ด์ setInterval์ count๊ฐ 0์ธ ์ํ์์ +1์ ๊ณ์ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ๋งค ์๊ฐ์๊ฐ ๊ฐฑ์ ๋ count๊ฐ์ ๊ธฐ์ค์ผ๋ก 1์ด ์ฆ๊ฐํด์ผํ๊ธฐ ๋๋ฌธ์ ํ์ฌ state ๊ฐ์ ๊ณ ๋ คํ๋ ๋ฐฉ์์ผ๋ก setCount(curr => curr+1); ๋ผ๊ณ ํด์ค์ผ ์นด์ดํธ๊ฐ ๊ณ์ ์ฆ๊ฐ๋๋ค.
const App = () => {
const [num, setNum] = useState(0);
const [count, setCount] = useState(0);
const handleClick = () => {
setNum(curr => curr + 1);
}
useEffect(() => {
setCount(num);
}, [num]);
return (
<div>
<p>๋ฒํผ {count}๋ฒ ๋๋ฆ</p>
<button onClick={handleClick}>๋ฒํผ</button>
</div>
)
}
๋ฒํผ์ ๋๋ฅผ๋๋ง๋ค ํ๋ฉด์ ๋์ค๋ "๋ฒํผ n๋ฒ ๋๋ฆ" ํ
์คํธ์ n์ด 1์ฉ ์ฆ๊ฐํ๋ ํ์ฐฎ์ ์ปดํฌ๋ํธ์ด๋ค.
side effect ์ ์ธ ๋ด์ฉ์ ์๋์ง๋ง ์ค๋ช
์ฉ์ผ๋ก ๊ทธ๋ฅ ๊ฐ๋จํ๊ฒ ๋ง๋ฌ...
๋ฒํผ์ ํด๋ฆญํ๋ฉด num์ด 1์ฉ ์ฆ๊ฐํ๋๋ฐ, useEffect์ Deps ๋ฐฐ์ด์ ์ด num์ ๋ฃ์ผ๋ฉด num์ด ์ํ๊ฐ ๋ณํ ๋๋ง๋ค useEffect์ Callback์ด ์คํ๋๋ค.
๋ฐ๋ผ์ ๋ฒํผ์ ํด๋ฆญํ์ฌ num์ ๊ฐ์ด ์ฆ๊ฐํ๋ฉด setCount(num)์ด ์คํ๋์ด count์ ๊ฐ๋ num๊ฐ๊ณผ ๊ฐ์์ง๊ฒ ๋๋ฏ๋ก "๋ฒํผ n๋ฒ ๋๋ฆ" ์ n์ ๋ฐ์์ด ๋๊ฒ ๋๋ค.
์ด๋ ๊ฒ ์ด๋ ํ state๊ฐ ๋ณํ ๋ ์คํ์ํฌ ๋ก์ง์ ์ ์ํ๋ ์ฉ๋๋ก ์ฐ๋ ค๋ฉด Deps ๋ฐฐ์ด์ ๋ณํ๋ฅผ ๊ฐ์งํ ๋ณ์๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
useEffect์ Callback์์ ํจ์๋ฅผ ๋ฆฌํดํด์ฃผ๋ฉด ๊ทธ ํจ์๋ ์ปดํฌ๋ํธ๊ฐ unmount ๋ ๋ ์คํ๋๋ค.
๊ฐ๋จํ๊ฒ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋๋ ๊ฒ์ mount, ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ผ์ง๋๊ฒ(๋ฆฌ๋ ๋๋ง ๋๊ธฐ ์ง์ )์ unmount๋ผ๊ณ ํ๋ค.
์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋๊ธฐ ์ํด unmount๊ฐ ๋ ๋ Callback ํจ์์์ ๋ฆฌํดํ๋ ํจ์๊ฐ ์คํ๋๋๋ฐ ์ด ํจ์๋ฅผ clean-up ํจ์๋ผ๊ณ ํ๋ค.
์ด๋ ๊ฒ ๊ธ๋ก๋ง ๋ณด๋ฉด ์ดํด๊ฐ ์๋๋ ์ด๊ฒ๋ ๊ฐ๋จํ ์์๋ฅผ ์ดํด๋ณด์.
function App() {
const [render, setRender] = useState(true);
console.log(render);
useEffect(() => {
console.log("์นด์ดํธ ์์!");
return () => {console.log("์นด์ดํธ ์ข
๋ฃ!")}
})
const handleClick = () => {
setRender(curr => !curr);
}
return (
<div className="App">
<button onClick={handleClick}>๋ฆฌ๋ ๋๋ง</button>
</div>
);
}
Deps๊ฐ ์๋ ๊ฒฝ์ฐ์ ์์ ์ฝ๋์์ useEffect์ clean-up ํจ์๋ง ์ถ๊ฐํ ์ฝ๋์ด๋ค.
์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋๊ธฐ ์ํด unmount๊ฐ ๋ ๋ Callback ํจ์์์ ๋ฆฌํดํ๋ ํจ์๊ฐ ์คํ๋๋ค๋ ์ฌ์ค์ ์ฃผ๋ชฉํ๋ฉฐ ์ด๋ค ์์๋ก ์ฝ์์ด ์ถ๋ ฅ๋ ์ง ์๊ฐํด๋ณด์.
์ฒ์ ๋ ๋๋ง ๋๋ฉด 3๋ฒ์งธ์ค console.log(render)์ ์ํด ์ฝ์์ฐฝ์ true๊ฐ ๋์ค๊ณ "์นด์ดํธ ์์!"์ด ์ถ๋ ฅ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฒํผ์ ๋๋ฌ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋๋ฉด ์ผ๋จ ์ปดํฌ๋ํธ๊ฐ unmount๋ ๋๋ ๊ทธ๋ "์นด์ดํธ ์ข ๋ฃ!"๊ฐ ์ถ๋ ฅ๋๊ณ , ๊ณง๋ฐ๋ก ์ปดํฌ๋ํธ๊ฐ mount๋๋ฉด ๋ฐ์ ๋ render๊ฐ์ธ false๊ฐ ๋์ค๊ณ "์นด์ดํธ ์์!"์ด ๋์ฌ๊ฒ์ด๋ค.
์ด๋ฐ ํ๋ฆ์ผ๋ก, ๋ฒํผ์ ๊ณ์ ๋๋ฅด๋ฉด ์ฝ์์ฐฝ์๋ ๋ค์๊ณผ ๊ฐ์ ์์๋ก ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋ ๊ฒ์ด๋ค.
true -> ์นด์ดํธ ์์! -> ์นด์ดํธ ์ข ๋ฃ! -> false -> ์นด์ดํธ ์์! -> ์นด์ดํธ ์ข ๋ฃ! -> true -> ...
๊ทผ๋ฐ ์ค์ ๋ก ํด๋ณด๋ฉด ์ด์ง ๋ค๋ฅด๋ค.
์..๋ถ๋ช ์ปดํฌ๋ํธ๊ฐ unmount๋ ๋ clean-up ํจ์๊ฐ ์คํ๋๊ณ ์ปดํฌ๋ํธ๊ฐ ๋ค์ ๋ ๋๋ง๋์ด ํจ์ ๋ก์ง์ด ์คํ๋๋๊ฒ ๋ง๋ค๋ฉด ์ฝ์์ฐฝ์๋ '์นด์ดํธ ์์!' ๋ค์์ '์นด์ดํธ ์ข ๋ฃ!'๊ฐ ๋จผ์ ๋์์ผ ํ๋๋ฐ ์๋ก์ด render๊ฐ์ด ๋จผ์ ๋์ค๊ณ ์๋ค.
์ฌ์ค clean-up ํจ์๋ ์ปดํฌ๋ํธ๊ฐ unmount๋ ๋ ์คํ๋๋ ํจ์๋ ๋ง์ง๋ง, ์ ํํ๋ ์ปดํฌ๋ํธ๊ฐ unmount ๋๊ณ ์ปดํฌ๋ํธ๊ฐ ๋ค์ ๋ ๋๋ง ๋๊ณ ๋์ useEffect ํจ์๊ฐ ์คํ๋๊ธฐ ์ง์ ์ ์คํ๋๋ค.
์ฆ ์ ํํ ์์๋ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง(unmount -> mount)๋ ๋
์ ์์์ธ ๊ฒ์ด๋ค.
์๊น ์ฒ์ ์์ํ ์์๋ 1324์ธ ๊ฒฝ์ฐ์ ์๊ธฐ์๊ณ ์ค์ ๋ก๋ 1324๊ฐ ์๋๋ผ 1234์๋๊ฒ!
๊ทธ๋์ useEffect ์ ์ ๋ก์ง์ธ console.log(render)๊ฐ ์คํ๋๊ณ ์๋ก์ด useEffect๊ฐ ์คํ๋ ๋ ์ ์ useEffect์ clean-up ํจ์๊ฐ ํธ์ถ๋ ๋ค ์๋ก์ด useEffect๊ฐ ์คํ๋๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์ค๊ฒ ๋๋ค.
clean-up ํจ์๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ๋ํ์ ์ธ ์๋ก setInterval์ ์ฌ์ฉํ๋ useEffect๊ฐ ์๋ค.
์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋ ๋๋ง๋ค useEffect๊ฐ ์คํ๋๋ค๋ฉด ์์ side effect ํํธ์์ ๋ดค๋ setInterval์ ์ค์ฒฉ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค. ์ด๋ clean-up ํจ์๋ก clearInterval ๋ก์ง์ ์ถ๊ฐํด์ค๋ค๋ฉด ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋ ๋ ๊ธฐ์กด์ setInterval์ clear ํด์ฃผ๊ธฐ ๋๋ฌธ์ ์๋ก ์คํ๋๋ useEffect์ setInterval ๋ก์ง์ด ์ค์ฒฉ๋ ์ผ์ด ์๋ค.
์ด์ฒ๋ผ clean-up ์ด๋ผ๋ ์ด๋ฆ๋๋ก, ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง ์ ๊ธฐ์กด useEffect์ ๋ก์ง์ ํ์คํ ๋๋ด์ผํ ํ์๊ฐ ์์๋ ์ฌ์ฉํ๋ ํจ์๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
useEffect๋ ์๊ณ ์๋ ๊ฐ๋
์ด๋ผ ์ ๋ฆฌ๊ฐ ์ผ๋ง ์๊ฑธ๋ฆด์ค ์์๋๋ฐ.. ์ ๋ฆฌํ๋ค๋ณด๋ ์๊ฐ๋ณด๋ค ์ ๋ชฐ๋๋ ๋ถ๋ถ์ด ๋ง์์ ์ด๊ฒ์ ๊ฒ ์ฐพ์๋ณด๋ฉด์ ์ ๋ฆฌํ๋ค๋ณด๋ ๊ต์ฅํ ์ค๋๊ฑธ๋ ธ๋ค ใ
์์ฒญ ๊น๊ฒ ํ๊ฒ๋ ์๋๊ฑฐ๊ฐ์๋ฐ..
์ญ์ ์ ํํ ์๋์ง ํ์
ํ๊ธฐ ์ํด์๋ ์ค๋ช
ํ๋ฏ์ด ์ ๋ฆฌํ๋ฒ ํด๋ณด๋๊ฒ ์ต๊ณ ์ธ๋ฏ ๐
์ด์จ๋ ์ ๋ฆฌํ๋ค๋ณด๋ ์ฅํฉํด์ก๋๋ฐ ์ํผ ๊ฒฐ๋ก !
useEffect์ ํจ๋ฅ
- ์ด๋ค ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ง ๋ชจ๋ฅด๋ side effect๊ฐ์ ๋๋ค์ ๊ฒฉ๋ฆฌ์ํฌ ์ ์๋ค
- ๊ฒฉ๋ฆฌ์ํจ side effect๋ฅผ ์ํ๋ ํ์ด๋ฐ์ ์คํ๋๋๋ก ๊ด๋ฆฌํ ์ ์๋ค
- clean-up ํจ์๋ฅผ ์ ์ ํ ํ์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ ํ๋ก๊ทธ๋จ์ ๊ณผ๋ถํ๋ฅผ ์๋ฐฉํ ์ ์๋ค
์ฐธ๊ณ ์๋ฃ
https://points.tistory.com/86
https://choar816.tistory.com/163#google_vignette
https://simsimjae.tistory.com/401
์ฆ๊ฒ๊ฒ ์ฝ์์ต๋๋ค. ์ ์ฉํ ์ ๋ณด ๊ฐ์ฌํฉ๋๋ค.