[React] useEffect (๋ผ์ดํ์ฌ์ดํด, Dependency array)
๐กuseEffect๋?
- React์์ ์ปดํฌ๋ํธ์ ๋ผ์ดํ์ฌ์ดํด์ ๋ค๋ฃจ๊ธฐ ์ํ ๋ํ์ ์ธ Hook์ด๋ค.
- ์๋ช ์ฃผ๊ธฐ ๋ณ ํน์ ๋ก์ง์ ์ํํ ์ ์๋๋ก ํด์ค๋ค.
- ์ ํต์ ์ธ ํด๋์คํ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ componentDidMount, componentDidUpdate, componentWillUnmount๋ฅผ ํจ์ํ ์ปดํฌ๋ํธ์์๋ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ Hook์
= ์ฃผ๊ธฐ๋ณ ์ฌ์ด๋ ์ดํํธ(side effect)๋ฅผ ์ ์ดํ๋ค.
* ๋ฆฌ์กํธ ๋ผ์ดํ์ฌ์ดํด ( life-cycle )
: Mount(ํ์)- Update(๋ณํ)- Unmount(์ฃฝ์) ์ผ๋ก ๊ตฌ์ฑ
์๋์ ์์ ์ฝ๋๋ฅผ ํตํด useEffect๋ฅผ ์ ๋ฆฌํด๋ณด์.
// App.jsx
import './App.css'
import Viewer from "./components/Viewer";
import Controller from "./components/Controller";
import Even from './components/Even';
import {useState, useEffect, useRef } from 'react';
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState("");
//false: ์์ง ์ด ์ปดํฌ๋ํธ๋ ๋ง์ดํธ๋์ง์์๋ค ์๋ฏธ
const isMount =useRef(false);
// 1. ๋ง์ดํธ: ํ์ (callbackํจ์ ๋ง๋ค๊ณ , deps์๋ ๋น ๋ฐฐ์ด ๋ฃ์)
useEffect(()=>{
console.log("mount");
},[]);
// 2. ์
๋ฐ์ดํธ: ๋ณํ, ๋ฆฌ๋ ๋๋ง
useEffect(()=>{
if(!isMount.current){
isMount.current= true;
return;
}
console.log("update");
});
// 3. ์ธ๋ง์ดํธ: ์ฃฝ์
useEffect(()=>{
console.log(`count: ${count}`);
console.log(`input:${input}`);
},[count,input])
const onClickButton = (value)=>{
setCount(count + value);
};
return (
<div className ="App">
<h1>Simple Counter</h1>
<section>
<input value={input} onChange={(e)=>{
setInput(e.target.value);
}}/>
</section>
<section>
<Viewer count={count}/>
{count %2===0 ? <Even/> : null}
</section>
<section>
<Controller onClickButton={onClickButton}/>
</section>
</div>
);
}
export default App;
// Even.jsx
import {useEffect} from "react";
const Even =() =>{
useEffect(()=>{
// ํด๋ฆฐ์
(์ ๋ฆฌํจ์)
// mount ๋ ๋ ์คํ, amount๋ ๋ ์ข
๋ฃ๋๋ฉด ์ ๋ฆฌํจ์ ํธ์ถ๋จ!
return () =>{
console.log("unmount");
};
},[]);
return <div>์ง์์
๋๋ค</div>;
};
export default Even;
โ๏ธ๋ง์ดํธ ์์ : ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ํ๋ฉด์ ๋ํ๋ ๋
useEffect(() => {
console.log("mount");
}, []);
์ ์ฝ๋๋ ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ๋ง์ดํธ๋ ๋ ํ ๋ฒ๋ง ์คํ๋๋ค.
*dependency array๋ฅผ ๋น ๋ฐฐ์ด([])๋ก ์ฃผ์๊ธฐ ๋๋ฌธ์ด๋ค.
→ ๋น ๋ฐฐ์ด์ ์ฃผ๋ฉด, ํด๋น useEffect๋ ์ค์ง ์ฒ์ ๋ ๋๋ง๋ ๋๋ง ์คํ๋๋ค.
์ฃผ๋ก API ํธ์ถ, ์ด๊ธฐ ์ธํ ๋ฑ์ ์ฌ์ฉ๋๋ค.
๐กDependency array๋?
= (deps , ์์กด์ฑ ๋ฐฐ์ด)
- useEffect ์์ ์ธ์ effect ํจ์๊ฐ ์คํ๋ ์ง๋ฅผ ์ ์ดํ๋ ์ญํ ์ ํ๋ค.
→ ์ด๋ค ์ํ๋ props๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง effect๊ฐ ์คํ๋๊ฒ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉํจ.
๐ useEffect๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ๋ ๋๋ง๋ง๋ค ์คํ๋จ์ผ๋ก,
์์กด์ฑ ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด ์์ ์๋ ๊ฐ๋ค์ด ๋ณ๊ฒฝ๋ ๋๋ง useEffect๊ฐ ์คํ๋๋๋ก ์ ํํ ์ ์๋ค.
โ๏ธ์ ๋ฐ์ดํธ ์์ : 1. ํน์ ๊ฐ์ด ๋ฐ๋ ๋
useEffect(() => {
console.log(`count: ${count}`);
console.log(`input: ${input}`);
}, [count, input]);
์ด ์ฝ๋๋ count ๋๋ input ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์คํ๋๊ณ ์๋ค.
→ dependency array์ ๋ค์ด๊ฐ ๋ณ์๋ค์ด ๋ฐ๋๋ฉด, ๊ทธ์ ๋ฐ๋ผ ํด๋น useEffect๋ ๋ค์ ์คํ๋๋ค.
์ด๋ฅผ ํตํด ํน์ ์ํ(state)๊ฐ ๋ฐ๋์์ ๋ ๋ก์ง์ ๋ถ๋ฆฌํ์ฌ ์ํํ ์ ์์ผ๋ฉฐ, ๋ฌด๋ถ๋ณํ ๋ฆฌ๋ ๋๋ง์ ๋ฐฉ์งํ ์ ์๋ค.
์ด์ฒ๋ผ useEffect๋ ์ ํ์ ์ผ๋ก ๋ฆฌ๋ ๋๋ง ๋ก์ง์ ์คํํ ์ ์๋๋ก ๋์์ค๋ค.
โ๏ธ์ ๋ฐ์ดํธ ์์ : 2. ์กฐ๊ฑด์ถ๊ฐ
const isMount = useRef(false);
useEffect(() => {
if (!isMount.current) {
isMount.current = true;
return;
}
console.log("update");
});
์ ์ฝ๋๋ ๋ชจ๋ ๋ ๋๋ง๋ง๋ค ์คํ๋์ง๋ง, ์ฒ์ ๋ง์ดํธ ์์ ์๋ ์คํ์ ๋ง๊ธฐ ์ํด useRef๋ฅผ ์ฌ์ฉํ๋ค.
isMount๋ผ๋ ref ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฒ์์ false๋ก ์ค์ ํ๊ณ , ๋ง์ดํธ ์ดํ๋ถํฐ๋ง console.log("update")๊ฐ ์ฐํ๋๋ก ์ฒ๋ฆฌํ์๋ค.
useRef hook์ ํ์ฉํด์ ์ผ๋ฐ์ ์ธ ๋ง์ดํธ/์ ๋ฐ์ดํธ ๊ตฌ๋ถ์ด ํ์ํ ์ํฉ์์ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
โ๏ธ์ธ๋ง์ดํธ ์์ : ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ผ์ง ๋
useEffect(() => {
return () => {
console.log("unmount");
};
}, []);
์ด ์ฝ๋๋ Even ์ปดํฌ๋ํธ์์ ์ฌ์ฉ๋์์ผ๋ฉฐ, ํด๋น ์ปดํฌ๋ํธ๊ฐ ํ๋ฉด์์ ์ ๊ฑฐ๋ ๋ ์ฝ์์ "unmount"๋ฅผ ์ถ๋ ฅํ๋ค.
useEffect์ return ๊ตฌ๋ฌธ์ *ํด๋ฆฐ์ ํจ์๋ก์, ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ผ์ง ๋ ์ ๋ฆฌ ์์ ์ ์ํํ ์ ์๋๋ก ํด์ค๋ค.
(์๋ฅผ ๋ค์ด, ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ, ํ์ด๋จธ ์ ๋ฆฌ, ๋ฉ๋ชจ๋ฆฌ ํด์ ๋ฑ์ ์ด๋ ๊ฒ ๊ตฌํํ ์์๋ค.)
๐กํด๋ฆฐ์ ํจ์(clean-up function) ์ด๋?
- ์ปดํฌ๋ํธ๊ฐ ์ธ๋ง์ดํธ๋๊ฑฐ๋(= ํ๋ฉด์์ ์ฌ๋ผ์ง๊ฑฐ๋), effect๊ฐ ๋ค์ ์คํ๋๊ธฐ ์ง์ ์ ์ํ๋๋ ์ ๋ฆฌ ์์
→ ๋ถํ์ํ ๋์ ์ค๋จ์ ์ํด ์ฌ์ฉ
useEffect(() => {
// effect ์คํ ๋ก์ง
console.log("Effect ์คํ");
return () => {
// ํด๋ฆฐ์
ํจ์
console.log("Effect ์ ๋ฆฌ");
};
}, [์์กด์ฑ ๋ฐฐ์ด]);
๋ ๋๋ง๋๋ ํ๋ฉด
์ฒ์ mount๋ ๋๋ฅผ ์ ์ธํ๊ณค update๋ฅผ ์ถ๋ ฅํ๊ณ ์์์ ํ์ธํ ์ ์๋ค.
๐ก์ ๋ฆฌ
์คํ ์์ | ์ฝ๋ ์์ | ์ค๋ช |
Mount | useEffect(() => {}, []) | ์ฒ์ ๋ ๋๋ง๋ ๋ ํ ๋ฒ๋ง ์คํ |
Update | useEffect(() => {}, [dep]) | ํน์ ๊ฐ(dep)์ด ๋ฐ๋ ๋๋ง๋ค ์คํ |
Unmount | useEffect(() => return () => {}, []) | ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ผ์ง ๋(clean-up) ์คํ |
๋ฌด์กฐ๊ฑด ์คํ | useEffect(() => {}) | ๋ชจ๋ ๋ ๋๋ง๋ง๋ค ์คํ(์์กด์ฑ ๋ฐฐ์ด ์์) |
React์์ useEffect๋ ๋จ์ํ ์ฌ์ด๋ ์ดํํธ ์ฒ๋ฆฌ ๋๊ตฌ๊ฐ ์๋๋ผ, ์ปดํฌ๋ํธ์ ๋ผ์ดํ์ฌ์ดํด์ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ด๋ค.
ํนํ dependency array์ ํ์ฉ์ ๋ฆฌ๋ ๋๋ง ์ต์ ํ์ ์ ์ง๋ณด์์ฑ ์ธก๋ฉด์์ ํ์์ ์ธ ๊ฐ๋ ์ด๋ค.
*Ref
https://ko.react.dev/reference/react/useEffect
useEffect – React
The library for web and native user interfaces
ko.react.dev
์ค๋ช ์ด ๋ถ์กฑํ ๋ถ๋ถ์ด๋ ํผ๋๋ฐฑ์ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์!
๊ฐ์ฌํฉ๋๋ค โบ๏ธ