React์์ ํจ์ ์ปดํฌ๋ํธ์ rendering์ด๋, state, props๋ฅผ ๊ธฐ๋ฐ์ผ๋ก UI์์๋ฅผ ๊ทธ๋ ค๋ด๋ ํ์๋ฅผ ๋งํ๋ค. ๋๋๋ง์ ๊ฒฐ๊ณผ๋ฌผ์ UI์์ ์ฆ, ํ๋ฉด์ JSX๋ฌธ๋ฒ์ผ๋ก ๋ฌด์์ด ๋ํ๋ ์ง๋ฅผ ์ ์ด๋ ์ปดํฌ๋ํธ๋ค์ด๋ผ๊ณ ํ ์ ์๋ค. ๋๋๋ง ๊ฒฐ๊ณผ๋ฌผ์ ์ํฅ์ ์ฃผ๋ ์์๋ state์ props์ด๋ค.
์ด๋ฅผ ๋ฌ๋ฆฌ ํํํ์๋ฉด (state, props) = UI ๋ผ๊ณ ํ ์ ์๋ค. ๊ทธ๋ฌ๋๊น input(state&props) ์ ๋ฐ๋ผ ๋ค๋ฅธ output(UI)์ ํํํ๋ ํจ์(function)์๋ ๊ตฌ์กฐ์ ์ผ๋ก ๋์ผํ๋ค.
์ผ์ชฝ์์ ์ถ๋ฐํ ๋ฐ์ดํฐ๊ฐ render๋ผ๋ ํจ์๋ฅผ ๊ฑฐ์ณ ์ค๋ฅธ์ชฝ์ JSX์์๋ก ๋ฆฌํด๋ ์์ด๋ค.
๋ถ์์ฉ, ๋ถ์ํจ๊ณผ๋ผ๊ณ ๋ ๋ถ๋ฅด๋ side Effect๋ ์ผ์ ์ํ์ ๋งฅ๋ฝ์์๋ ๋ถ์ ์ ์ธ ์๋ฏธ๋ก ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ง๋ง, ํ๋ก๊ทธ๋๋ฐ ์ธก๋ฉด์์๋ ๋จ์ํ ๋ถ์ ์ ์ธ ์๋ฏธ๋ก๋ง ์ฌ์ฉ๋์ง ์๋๋ค.
์ปดํจํฐ ๊ณผํ์์ ํจ์๊ฐ ๊ฒฐ๊ณผ๊ฐ ์ด์ธ์ ๋ค๋ฅธ ์ํ๋ฅผ ๋ณ๊ฒฝ์ํฌ ๋ ๋ถ์์ฉ์ด ์๋ค๊ณ ๋งํ๋ค. (wikipedia)
let count = 0
function greetWithSideEffect(name) { // Input
count = count + 1 // Side Effect!
return `${name}๋ ์๋
ํ์ธ์!` // Output
}
greetWithSideEffect()๋ผ๋ ํจ์๋ ์ด๋ฆ์ ๋ฐ์ ์ธ์ฟ๋ง์ ๋ฆฌํดํ๋ ํจ์๋ค.
์ด ํจ์๋ ๋จ์ํ input๊ณผ output๋ง ์กด์ฌํ๋ ํจ์๊ฐ ์๋๋ค. ์คํํ๋ ์ค๊ฐ์ ์๋ํํฐ์ ์๋ count๋ผ๋ ๋ณ์๋ฅผ ์กฐ์ํ๋ค. ์ด๋ ํจ์์ ๊ฒฐ๊ณผ๊ฐ ์ด์ธ์ ๋ค๋ฅธ ์ํ๋ฅผ ๋ณ๊ฒฝ์ํค๋ ํ์์ด๋ฏ๋ก side Effect๋ผ ํ ์ ์๋ค.
์ด๋ฌํ ์ผ์ ํจ์ ์ปดํฌ๋ํธ์์๋ ์ผ์ด๋ ์ ์๋ค. ์ฆ, ํจ์ ์ปดํฌ๋ํธ์์์ side Effect๋ ๋๋๋ง์ด ์๋๊ณ ์ธ๋ถ ์ธ๊ณ์ ์ํฅ์ ์ฃผ๋ ์ด๋ ํ ํ์์ด๋ค.
๋ํ์ ์ผ๋ก Data Fetching, DOM ์ง์ ์ ๊ทผ(ex. Event Listener ๋ฑ๋ก), ๊ตฌ๋
(ex. SetInterval)๊ณผ ๊ฐ์ ํ์๋ค์ด ์๋ค. ์ด๋ค ๋ชจ๋๊ฐ ์ปดํฌ๋ํธ์์ ๊ผญ ํ์ํ ๋ํ์ ์ธ side Effect์ด๋ค.
์์์ ํจ์ ์ปดํฌ๋ํธ์ ๋ฆฌํด ๊ฐ์ UI ์์์ด๋ฉฐ state, props์ ๋ณํ๊ฐ ์์ ๋๋ง๋ค ํจ์๊ฐ ์คํ๋๋ค๊ณ ํ๋ค. ์ด ๋ง์ ๋งค ๋๋๋ง ์ body์ ์๋ ๋ก์ง์ด ์คํ๋๋ค๋ ๋ป์ด๋ค(ํ ๋ฒ๋ง ๋๋๋ง๋๋ ๋๋ ๊ฒ๋ ๊ณ์ํด์ ๋๋๋ง ๋๋ค๋ ๋ง). ๋๋๋ง๊ณผ ๋ฌด๊ดํ ๋ก์ง์ด ๋๋๋ง ๊ณผ์ ์์ ์คํ๋๊ธฐ ๋๋ฌธ์ ๋๋๋ง ์์ฒด์ ์ํฅ์ ์ฃผ์ด ์ฑ๋ฅ๋ฉด์์ ์ ์ํฅ์ ๋ผ์น ์ ์๋ค.
function greetWithSideEffect({ name }) { // Input
// Bad!
document.title = `${name}๋ ์๋
ํ์ธ์!`; // Side Effect
return <div>{`${name}๋ ์๋
ํ์ธ์!`}</div>; // Output
}
React์์๋ ์ด๋ฐ side Effect๋ฅผ ์ผ์ผํค๊ธฐ ์ ์ ํ ์ฅ์๋ก useEffect hook์ ์ ๊ณตํ๋ค.
๊ณต์๋ฌธ์์๋ "React์ ์์ํ ํจ์์ ์ธ ์ธ๊ณ์์ ๋ช
๋ น์ ์ธ ์ธ๊ณ๋ก์ ํ์ถ๊ตฌ๋ก ์๊ฐํ์ธ์"๋ผ๊ณ ์ค๋ช
ํ๊ณ ์๋๋ฐ, ๋ฌด์จ ๋ง์ธ์ง ๋ชจ๋ฅด๊ฒ ๋ค.
์ฌ๊ธฐ์ "์์ํ ์ธ๊ณ"๋ ๋๋๋ง(input -> output)์ ๋ปํ๊ณ , ๋๋๋ง ์ด์ธ์ ์ผ์ผ์ผ์ผ ํ๋ side Effect๋ฅผ ์ผ์ผํฌ ํ์ถ๊ตฌ๋ก useEffect๋ฅผ ์ฌ์ฉํ๋ผ๋ ๋ง์ด๋ค.
useEffect๋ side Effect๋ฅผ ๋๋๋ง ์ดํ์ ๋ฐ์์ํจ๋ค(์์ธ๊ฐ ์๋๋ฐ useLayoutEffect ์ด๋ค).useEffect๊ฐ ์ํ๋๋ ์์ ์ ์ด๋ฏธ DOM์ด ์
๋ฐ์ดํธ ๋์์์ ๋ณด์ฅํ๋ค๋ ๋ป์ด๊ณ , ๋ฌ๋ฆฌ ๋งํ๋ฉด side Effect๊ฐ ๋๋๋ง์ ์ํฅ์ ์ฃผ์ง ์๋๋ก ์ค๊ณ๋์์์ ๋ปํ๋ค.
import { useEffect } from 'react';
function greetWithSideEffect({ name }) { // Input
useEffect(() => {
// Good!
document.title = `${name}๋ ์๋
ํ์ธ์!`; // Side Effect
}, [name]);
return <div>{`${name}๋ ์๋
ํ์ธ์!`}</div>; // Output
}
๋ง์ฝ side Effect ์ดํ ์
๋ฐ์ดํธ ๋ ์ ๋ณด๊ฐ ์์ด ์๋กญ๊ฒ ํ๋ฉด์ด ๊ทธ๋ ค์ ธ์ผ ํ ๊ฒฝ์ฐ(state, props์ ์
๋ฐ์ดํธ) ์๋กญ๊ฒ ๋๋๋ง์ ์ผ์ผํจ๋ค.
ํจ์ ์ปดํฌ๋ํธ๋ ๊ฐ์ฅ ์ต์ ํ๋ state์ props๋ฅผ ๋ฐ์ํด ํ๋ฉด์ ๋ฟ๋ ค์ค๋ค. Effect๋ฅผ ์ผ์ผํฌ ํ์ด๋ฐ์ useEffect์ ๋ ๋ฒ์งธ ์ธ์์ธ ์์กด์ฑ ๋ฐฐ์ด(Dependency Array)๋ฅผ ํตํด ํํํ๋ค.
useEffect์ ๋ค๋ฅธ ํํ ์ฌ์ฉ.
๋ ๋ฒ์งธ ์ธ์์ ๊ฐ์งํ ๊ฐ์ ๋ฐฐ์ด๋ก ๋๊ฒจ์ฃผ๋ฉด ํด๋น ๊ฐ๋ค์ด ๋ณ๊ฒฝ๋์์ ๋๋ง ์คํ๋๊ฒ ํ ์ ์๋ค.
import { useEffect } from "react"
// ์ฌ์ฉ๋ฒ
useEffect( ์คํ์ํฌ ๋์, [ ํ์ด๋ฐ ] )
document.addEventListener("ํ์ด๋ฐ", ์คํ์ํฌ ๋์) // ์ถ์ํ ํ ์์
// ๋งค ๋ ๋๋ง๋ง๋ค Side Effect๊ฐ ์คํ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ
useEffect(() => {
// Side Effect
})
// Side Effect๊ฐ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง ์ดํ ํ๋ฒ ์คํ ๋๊ณ ,
// ์ดํ ํน์ ๊ฐ์ ์
๋ฐ์ดํธ๋ฅผ ๊ฐ์งํ์ ๋๋ง๋ค ์คํ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ
useEffect(() => {
// Side Effect
}, [value])
// Side Effect๊ฐ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง ์ดํ ํ๋ฒ ์คํ ๋๊ณ ,
// ์ดํ ์ด๋ค ๊ฐ์ ์
๋ฐ์ดํธ๋ ๊ฐ์งํ์ง ์๋๋ก ํด์ผ ํ๋ ๊ฒฝ์ฐ
useEffect(() => {
// Side Effect
}, [])
์ ์ฝ๋๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ด๋ฉด,
::ํจ์ ์ปดํฌ๋ํธ์ ๋๋๋ง ์ ์ฐจ
1. ์ปดํฌ๋ํธ๊ฐ ๋๋๋ง ๋๋ฉด, ์ต์ด๋ก ์งํ๋๋ ๋๋๋ง์ ๋ธ๋ผ์ฐ์ ์ ์ฒ์์ผ๋ก ์ด ์ปดํฌ๋ํธ๊ฐ ๋ณด์ฌ์ก๋ค๋ ์๋ฏธ๋ก mount๋ผ๊ณ ํํ.
2. useEffect ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋๊ฒจ์ค ํจ์(callback)๊ฐ ์คํ๋๋ค(side Effect).
3. ๋ค์ ๋๋๋ง์ด ์ผ์ด๋๋ค(state๋ props๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ)
4. useEffect๋ ๋ ๋ฒ์งธ ์ธ์์ ๋ค์ด์๋ ์์กด์ฑ ๋ฐฐ์ด์ ์ฒดํฌํ๋ค.