useEffect๋ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋ ๋๋ง๋ค ํน์ ์์ (side effect)๋ฅผ ์ํํ๋๋ก ์ค์ ํ ์ ์๋ "Hook"์ด๋ค!..?
๊ทธ๋ ๋ค๋ฉด ์ฐ์ useEffect๊ฐ ์ด๋ป๊ฒ ์ ์๋์ด ์๋์ง ํ์ธํด๋ณด์!
useEffect()
๋ effect๋ผ๋ ํ์ ์ธ์ 1๊ฐ์ ์ต์ ๋ ์ธ์์ธ deps 1๊ฐ๋ฅผ ๋ฐ๋๋ค๊ณ ์ ์๋์ด์๋ค.effect
๋cleanup
ํจ์๋ฅผ ๋ฐํ ํ ์ ์๋ ๋ช ๋ น ํจ์๋ผ๊ณ ์ ์๋์ด ์๋ค.deps
๋ deps์ธ์๊ฐ ์กด์ฌํ๋ค๋ฉด, effect๋ deps ๋ฆฌ์คํธ ์์ ์๋ values๋ค์ด ๋ณํ ๋ ํ์ฑํ ๋ ๊ฒ์ด๋ผ๊ณ ์ ์๋์ด ์๋ค.
์.. ๊ทธ๋ผ ์ด์ useEffect๊ฐ ์ด๋ป๊ฒ ์ ์ ๋์ด์๊ณ , ๋์ํ๋์ง ์์๋ค.. ๊ทผ๋ฐ ์์ ๋์จ
side effect
์cleanup function
์ด ๋ญ์ง ๋ชจ๋ฅด๋๊น ์ฐพ์๋ณด๊ณ ๊ทธ ํ์ ์ง์ ์ฌ์ฉํด๋ณด์!
์ฐ์ ๋ฆฌ์กํธ์์
rendering
์ด ๋ฌด์์ ์๋ฏธํ๋์ง ์์์ผํ๋ค..
- React์์ ํจ์ ์ปดํฌ๋ํธ์
rendering
์ด๋ state, props๋ฅผ ๊ธฐ๋ฐ์ผ๋ก UI ์์๋ฅผ ๊ทธ๋ ค๋ด๋ ํ์์ด๋ค.- ์ฆ, ๋ ๋๋ง์ ๊ฒฐ๊ณผ๋ฌผ์ UI ์์, ๊ทธ๋ฌ๋๊น ํ๋ฉด์ JSX ๋ฌธ๋ฒ์ผ๋ก ๋ฌด์์ด ๋ํ๋ ์ง๋ฅผ ์ ์ด๋ ์ปดํฌ๋ํธ๋ค์ด๋ผ๊ณ ํ ์ ์๋ค. ๋ ๋๋ง์ ๊ฒฐ๊ณผ๋ฌผ์ ์ํฅ์ ์ฃผ๋ ์์๋ state์ props์ด๋ค.
- ์ด๋ฅผ ๋ฌ๋ฆฌ ํํํ๋ฉด
(state,props) => UI
๋ผ๊ณ ๋ ํํํ ์ ์๋ค.- ๋ค์ ๋งํ๋ฉด, state,props์ ๋ฐ๋ผ ๋ค๋ฅธ UI๋ฅผ ํํํ๋ ํจ์์๋ ๊ตฌ์กฐ์ ์ผ๋ก ๋์ผํ๋ค.
React๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ค์ฌ์ผ๋ก ํ๋ค.
- side effect๋ ์คํ ์ค์ธ ํจ์์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ๊ฒ์ ์ํฅ์ ๋ฏธ์น๋ ๋ชจ๋ ์คํ์ ๋งํ๋ค.
- ์๋ฅผ ๋ค์ด, ํจ์๊ฐ ์ ์ญ ๋ณ์๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ ํด๋น ํจ์๋ side effect๋ฅผ ์ ๋ฐํ๋ค.
- ์ ์ญ ๋ณ์๋ ํ์ฌ ํจ์์ ๋ฒ์์ ์ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
Side Effect ์์
- ๋ฐ์ดํฐ์ ๋ํ ๋น๋๊ธฐ API ํธ์ถ ๋ง๋ค๊ธฐ
- DOM ์์๋ฅผ ์๋์ ์ผ๋ก ์ ๋ฐ์ดํธ
- ํจ์ ๋ด๋ถ์์ ์ ์ญ ๋ณ์ ์ ๋ฐ์ดํธ
- Setting a subscription to an observable(ex, setInterval)
์ปดํฌ๋ํธ๊ฐ ํ์ํ ์์ ์ ์ํํ๋๋ก ํ๋ ค๋ ๊ฒฝ์ฐ side effect๋ ํผํ ์ ์๋ค.
1. ํ์ฌ ์ฌ์ฉ์์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ตฌ์ฑ ์์๊ฐ ํ์ํ๋ค๊ณ ๊ฐ์ ํด ๋ณด์.
2. ์ด๊ฒ์ ๋ง๋ค๊ธฐ ์ํด์, ์ง์ ๋ ์ฌ์ฉ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด AJAX ํธ์ถ์ ํด์ผ ํ๋ค. ๋ฐ๋ผ์, ์ฐ๋ฆฌ๋ ํจ์์ side effect๋ฅผ ๋์ ํ๊ณ ์๋ค.
3. side effect๋ผ๊ณ ํด๋, ํ์ํ ์์ ์ ์ํํ๋ ค๋ฉด ์ปดํฌ๋ํธ ๋ด๋ถ์ ํ์ํ๋ค.- ์ ์์ ์ ์์ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ์ฌ ํ ์คํธ ํด๋ดค๋ค. ์๋ ์ฝ๋๋ฅผ ๋ณด์.
import axios from "axios";
import { useEffect, useState } from "react";
import "./App.css";
import EffectTest from "./EffectTest";
import PropTest from "./PropTest";
function App() {
let [myName, setMyName] = useState("suhyeon");
let [textColor, setTextColor] = useState("green");
let [id, setId] = useState(1);
let [user, setUser] = useState({});
console.log("user", user);
console.log("id111", id);
useEffect(() => {
axios
.get(`https://jsonplaceholder.typicode.com/users/${id}`)
.then((res) => {
let temp = { ...res.data };
setUser(temp);
});
}, [id]);
// console.log(user.data);
const changeColor = (color) => {
textColor === "green" ? setTextColor(color) : setTextColor("green");
};
const nextId = () => {
console.log("prevId", id);
if (id < 10) setId(++id);
else if (id === 10) alert("์ ์ ๋ชฉ๋ก์ ๋์
๋๋ค.");
console.log("prevId", id);
};
const prevId = () => {
console.log("prevId", id);
if (id > 1) setId(--id);
else if (id === 1) alert("์ ์ ๋ชฉ๋ก์ ์์์
๋๋ค.");
console.log("prevId", id);
};
return (
<>
<PropTest
userInfo={[{ name: myName, age: "28" }]}
color={textColor}
clickEvent={changeColor}
/>
<EffectTest
color={textColor}
name={myName}
id={id}
nextEvent={nextId}
prevEvent={prevId}
/>
<div>name:{user.name}</div>
<div>username:{user.username}</div>
<div>email:{user.email}</div>
<div>phone:{user.phone}</div>
<div>website:{user.website}</div>
</>
);
}
export default App;
------------------------------------------------------------
import { useEffect } from "react";
function EffectTest({ id, nextEvent, prevEvent }) {
console.log("EffectTest ์ปดํฌ๋ํธ ์์");
useEffect(() => {
console.log("First useEffect");
});
return (
<div style={{ marginTop: 10 }}>
<button onClick={nextEvent}>next</button>
<button style={{ marginLeft: 15 }} onClick={prevEvent}>
prev
</button>
</div>
);
}
export default EffectTest;
์ ์ฝ๋๋ App ์ปดํฌ๋ํธ์ useEffect๋ฅผ ์ฌ์ฉํ์ฌ, ์ ์ id๊ฐ ๋ณ๊ฒฝ๋ ๋ side effect๋ฅผ ์ํํ๋๋ก ์์ฑํ์๋ค.(
useEffect() ๋ ๋ฒ์งธ ์ธ์๋ก [id] ๋ฅผ ์ ๋ฌํด์ id๊ฐ ๋ฐ๋ ๋ side effect๋ฅผ ์ฒ๋ฆฌํ๋ ๋ก์ง์ด๋ค.
)
- ์ฌ๊ธฐ์๋ EffectTest๋ผ๋ ์ปดํฌ๋ํธ๋ฅผ ์๋ก ๋ง๋ค์ด์ ๋ฒํผํ๊ทธ 2๊ฐ๋ฅผ ๋ฆฌํดํ๊ณ ์๋ค.
- ๋ฒํผํ๊ทธ์๋ props๋ก ์ ๋ฌ๋ฐ์ nextEvent, prevEvent ํจ์๋ฅผ onClick ์ด๋ฒคํธ์ ํธ๋ค๋ฌ๋ก ์ ๋ฌํ๊ณ ์๋ค.
- ์ 2๊ฐ์ ํจ์๋ฅผ ์ฐพ์๋ณด๋ ค๋ฉด App ์ปดํฌ๋ํธ๋ก ๊ฐ๋ณด์.
- nextEvent, prevEventํ๋กํผํฐ๋ช ์ผ๋ก ์ ๋ฌ๋ฐ์ 2๊ฐ์ ํจ์๋ nextId, prevId๋ผ๋ ํจ์์ด๋ค.
- ํจ์๋ค์ ๋ฒํผ์ด ํด๋ฆญํ ๋ id ์ํ๊ฐ์ ๋ณ๊ฒฝํ๋ ์ด๋ฒคํธ์ด๋ค.
- id๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค side effect์์ ์ด ์ํ๋๋๋ฐ, ์ฌ๊ธฐ์ side effect ์์ ์ axios ๋น๋๊ธฐ ์์ ์ ํตํด get()๋ฉ์๋ ์์ ์ธ์๋ก url์ ๋๊ฒจ์ฃผ๊ณ ๊ทธ url์ ์๋ ์ ๋ณด๋ค์ ๊ฐ์ง(์ฑ๊ณตํ๋ค๋ฉด) Promise ๊ฐ์ฒด๊ฐ ๋ฐํ๋๋๋ฐ, then() ๋ฉ์๋๋ก Promise ๊ฐ์ฒด์์ ๊ฐ์ ๋ฐ์ temp ๋ณ์์ ์๋ก์ด ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ user ์ํ๊ฐ์ ๋ฃ์ด์ฃผ๊ณ ์๋ค.
- ์ฆ, id๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ํด๋น id์ ํด๋นํ๋ ์ ์ ์ ๋ณด๊ฐ user ์ํ๊ฐ์ ๊ฐ์ฒด๋ก ๋ด๊ธฐ๋ ๊ฒ์ด๋ค.
- ๊ทธ user ์ํ๊ฐ์ ์ ๋ณด๋ฅผ JSX๋ฌธ๋ฒ ({})์ผ๋ก ์ถ์ถํ์ฌ ํ๋ฉด์ ์ถ๋ ฅํ๋ ์์ ์ด๋ค.
์ฝ๋๋ฅผ ์์ฑํ๋ฉด์ ๊ฒช์๋ ๋ฌธ์
- nextId, prevId ํจ์์์ ์ฆ๊ฐ์ฐ์ฐ์๋ฅผ id++, id--๋ก ์ฌ์ฉํ๋๋, 1๊ฐ์ฉ ์์ํ๋ ๊ฐ๋ค๋ณด๋ค ๋ฐ๋ ค์ ์ถ๋ ฅ๋๋ ํ์์ด ๋ฐ์ํ๋ค
=> ++id, --id๋ก ๋ณ๊ฒฝํ๋๋ ํด๊ฒฐ๋์๋ค. ํ์ ์ฐ์ฐ์๋ ๊ฐ์ ํ ๋นํ ๋ค 1์ ์ฆ๊ฐ/๊ฐ์์ํค๋ ์ฐ์ฐ์ด๊ณ , ์ ์ ์ฐ์ฐ์๋ ๊ฐ์ 1์ ์ฆ๊ฐ/๊ฐ์์ํจ ๋ค ํ ๋นํ๋ ์ฐ์ฐ์์๋ค.
=> ์ ์, ํ์ ์ฐ์ฐ์์ ์ฐจ์ด๋ฅผ ์ด๋ฒ์ ํ์คํ ๊ธฐ์ตํ๊ฒ ๋์๋ค.
๋ง์ฝ useEffect์ ๋ ๋ฒ์งธ ์ธ์๊ฐ ๋น ๋ฐฐ์ด(=[])์ด๋ผ๋ฉด?
์ฒซ ์ ์ ์์ ์ด์ ์ผ๋ก ๊ฐ๋ ค๊ณ ๋ฒํผ์ ๋๋ฅด๋ฉด alert์ฐฝ์ด ๋จ๋ ๊ฒ์ ํตํด id์ ๊ฐ์ด ๋ฐ๋์ง๋ง
[]
์ด ์ธ์๋ก ๋ค์ด์๊ธฐ ๋๋ฌธ์ ์ฒซ ๋ง์ดํธ ๋๋ง side Effect๊ฐ ๋์ํด์ ๊ธฐ๋ณธ ์ ์ ์ ๋ณด๊ฐ ์ถ๋ ฅ๋์ง๋ง ๊ทธ ๋ค์๋ถํฐ๋ side effect์์ ์ด ์ด๋ค์ง์ง ์์ ์ ์ ๊ฐ ๋ฐ๋์ง ์๋ ๊ฒ์ ํ์ธ ํ ์ ์๋ค.
useEffect๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ฒช์๋ ๋ฌธ์
useEffect์ 2๋ฒ์งธ ์ธ์๋ก ๋น ๋ฐฐ์ด๊ณผ, [id] ์ฒ๋ผ value๋ฅผ ๋ฃ์ deps๋ฅผ ์ ๋ฌํ์ ๋, ๋น ๋ฐฐ์ด์ ์ฒซ ๋ง์ดํธ๊ฐ ๋ ๋๋ง ์์ ์ด ์ด๋ค์ง๊ณ , value๊ฐ ์์ผ๋ฉด value๊ฐ ๋ณํ ๋ ์์ ์ด ์ด๋ค์ง๋ ๊ฒ ๊น์ง๋ ์ค์ ๋ก ํ์ธํ๊ณ ์ดํด๋ ํ๋ค.
๊ทธ๋ฐ๋ฐ... 2๋ฒ์งธ ์ธ์๋ฅผ ์์ ์ ๋ฌํ์ง ์์์ ๋ ํ๋ก๊ทธ๋จ์ด ์์์น ๋ชปํ ๋์์ ์ํํ๋ค. ์๋ ์บก์ณ ํ๋ฉด์ ๋ณด์.
- ๋ณด์ด๋ ๊ฒ์ฒ๋ผ id๊ฐ ๋ณ๊ฒฝ๋ ๋, side effect๊ฐ ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋๋ฐ, ์ฝ์์ฐฝ์ ๋ณด๋ฉด ๋ฆฌ๋ ๋๋ง์ด ๊ณ์ ์ด๋ค์ง๋ ๊ฒ ๊ฐ์๋ฐ, ์ด์ ๋ฅผ ๋ชจ๋ฅด๊ฒ ๋ค..
๐ก์! ์ด์ ๋ฅผ ์์๋ค.. useEffect์ 2๋ฒ์งธ ์ธ์๋ฅผ ์ ๋ฌํ์ง ์์์, ๋ ๋๋ง์ด ๋ ๋๋ง๋ค useEffect์ effect๊ฐ ์คํ๋๋๋ฐ, ํ์ฌ App ์ปดํฌ๋ํธ์ useEffect effect๋ฅผ ๋ณด๋ฉด ์๋์ ๊ฐ๋ค. setUser() ๋ถ๋ถ์ด ๋ฌธ์ ์๋ค.
โ๏ธ์ฆ, setUser๊ฐ ์ด๋ค์ง๋ฉด์ ์ํ๊ฐ์ด ๋ณ๊ฒฝ๋ผ์ ๋ฆฌ๋ ๋๋ง ๋๊ณ ๋ค์ App์ปดํฌ๋ํธ์ useEffect๊ฐ ์คํ๋๊ณ ๋ฐ๋ณต๋ผ์ ์ด๋ฐ ๊ฒ์ด๋ค. ํ์คํ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ๋ฉด์ ์ฝ์์ ์ถ๋ ฅํด๋ณด๋, ํ๋ก๊ทธ๋จ์ด ์ด๋ค ์์๋ก ๋์ํ๋์ง ์ดํด๊ฐ ๊ฐ๊ณ ์ง๊ธ๊ณผ ๊ฐ์ ์ํฉ๋ ์ดํด๊ฐ ๋ ๋นจ๋ฆฌ๋๋ ๊ฒ ๊ฐ์์ ๋คํ์ด๋ค..
=> ๊ณ์ ์ด๋ ๊ฒ ๊ณต๋ถํ์.. ๋ ๋ง์ด ์ฐพ์๋ณด๊ณ ..(์๋ฆฌ๋ถํฐ ์๋ฉด ์ฐธ ์ข์๊ฑธ... ์๋ฆฌ๋ถํฐ ์์๊ฐ๋๊ฒ ์ด๋ ค์ด ๊ฒ ๊ฐ๋ค..)
axios
.get(`https://jsonplaceholder.typicode.com/users/${id}`)
.then((res) => {
let temp = { ...res.data };
setUser(temp);
});
useEffect
๋ ๋ฉ์๋ ๋ด์์ ํจ์๋ฅผ ๋ฐํํ๋ ๋ฐฉ์์ผ๋ก ๋น๋๋๋ค. ๋ฐํ๋๋ ํจ์๋ ์ปดํฌ๋ํธ๊ฐ ์ฐ๊ฒฐ ํด์ ๋ ๋ ์คํ๋๋ค.(์ธ๋ง์ดํธ)
=> ์ด๊ฒ์ ๋ถํ์ํ ๋์์ ์ ๊ฑฐํ๊ฑฐ๋ ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ์ ์ฉํ๋ค.
์์ : Render -> Effect Callback -> CleanUp
- ์ฃผ์ํ ์ ์ ๋จ์ํ ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋๊ณ , ์ฌ๋ผ์ง๋ ์์ ์๋ง Cleanup Function์ด ์คํ๋๋๊ฒ ์๋๋ค.
- ๋ค์ effect๊ฐ ์ผ์ด๋๊ธฐ ์ ์, ์ด์ effect์ ์ํฅ์ ์ ๋ฆฌํด์ค์ผ ํ๋ค๋ ์ปจ์ ์ ๊ธฐ์ตํ์.
- ๋ค์ ์์ ๋ฅผ ๋ณด๊ณ ์์๋ฅผ ๋ง์ถฐ๋ณด์..
const App = () => {
const [count, setCount] = useState(0);
console.log("render", count);
useEffect(() => {
console.log("useEffect Callback", count);
return () => {
console.log("cleanUp", count);
});
}, [count]);
return <div onClick={() => setCount(count + 1)}>ํ์</div>;
};
export default App;
๋ด๊ฐ ์ฒ์ ์์ํ ์ถ๋ ฅ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ๋จผ์ , ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ ๋
render 0
- useEffect๋ ๋ ๋ฒ์งธ ์ธ์์ deps๊ฐ ์์ด๋ ์ฒซ ๋ง์ดํธ ๋ effect๊ฐ ์คํ๋๋ฏ๋ก,
useEffect Callback 0
์ด๋ ๊ฒ ๋ ๋จ๊ณ๋ฅผ ์์ํ๊ณ , ๋ฒํผ์ ๋๋ ์ ๋์ ์ถ๋ ฅ์ ์์ํ ๊ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.- setCount()๋ฅผ ํตํด count ์ํ๊ฐ์ 1์ด ๋ํด์ ธ ๋ ๋๋ง์ด ๋ค์๋ผ์
render 1
- useEffect์ ๋ ๋ฒ์งธ ์ธ์์ธ deps์ value๊ฐ ๋ณํ์ผ๋ฏ๋ก effect ์คํ,
useEffect Callback 1
์ด๋ ๊ฒ ๋ ๋จ๊ณ๋ฅผ ์์ํ๋ค. ํ์ง๋ง ์ค์ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋คrender 1
->cleanUp 0
->useEffect Callback 1
... ํ .. ์ ์ผ๊น..- ์๋ง๋ ์์์ ๋งํ ์ปจ์ ์ด ์ด๋ฐ ์ํฉ์ ๋งํ๋ ๊ฒ ๊ฐ๋ค.
๋ค์ effect๊ฐ ์ผ์ด๋๊ธฐ ์ ์, ์ด์ effect์ ์ํฅ์ ์ ๋ฆฌํด์ค์ผ ํ๋ค๋ ์ปจ์ ์ ๊ธฐ์ตํ์.
- ์ด์ effect ์ํฅ์ ์ ๋ฆฌํด์คฌ๊ธฐ ๋๋ฌธ์ ๋ฒํผ ํด๋ฆญ ์ ์ ์ํ๊ฐ 0๊ณผ ํจ๊ป ์ถ๋ ฅ๋ ๊ฒ์ด๋ค.
- React Hook Flow Diagram ์ฌ์ง์ ๋ณด๋ฉฐ ํ๋ฆ์ ์ดํด๋ณด์.
Render
-> Browser paints screen
-> CleanUp Effects
-> Run Effects
์์์ด๋ค.useEffect๋ React ํด๋์ค ๊ธฐ๋ฐ ์ปดํฌ๋ํธ์ ์๋ช ์ฃผ๊ธฐ ์ด๋ฒคํธ์ ๋ํ ๋์ฒด๋ก ๋ณผ ์ ์๋ค.
- ์์ง cleanup์ ๋ํด ์์ ํ ์ดํดํ์ง ๋ชปํด์, ์์ ์ฝ๋๋ฅผ ์ง์ ์์ฑํด๋ณด๋ฉด์ ์๋ฆฌ๋ฅผ ์ดํดํด์ผ ํ ๊ฒ ๊ฐ๋ค.
- useEffect๋ฅผ ๊ณต๋ถํ๋ฉด์ state๋ ๊ฐ์ด ๊ณต๋ถ๊ฐ ๋๋ค...
- ๊ฐ๋ ์ ๋ํ ์ดํด๋ ์ญ์ ์ง์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ถ๋ ฅํด๋ณด๋ฉด์ ๋ ๋นจ๋ฆฌ ๋๋ ๊ฒ ๊ฐ๋ค..
https://dev.to/otamnitram/react-useeffect-cleanup-how-and-when-to-use-it-2hbm
https://ko.reactjs.org/docs/hooks-effect.html