728x90
๐ React Hook ??
- ํจ์ํ ์ปดํฌ๋ํธ์์ ์ํ ๊ด๋ฆฌ์ ์๋ช ์ฃผ๊ธฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ.
๐ useState
- ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ํ(state)๋ฅผ ๊ด๋ฆฌํ ๋ ์ฌ์ฉ.
- ์ด๊ธฐํ
- const [name, setName] = useState("ํ๊ธธ๋");
- const [ ์คํ ์ดํธ ๋ณ์, ์ด ์คํ ์ดํธ ๋ณ์๋ฅผ update ๋ฅผ ํ ์ ์๋ ํจ์ ] = useState("์ด๊ธฐ๊ฐ ๋ฃ๊ธฐ");
- --> name = "ํ๊ธธ๋" ์ผ๋ก ์ด๊ธฐ๊ฐ์ด ๋ฃ์ด์ง ์ํ๋ก ์์ํจ.
- ๋จ์ผ ๋ฌธ์, ๋จ์ผ ์ซ์, ๋ฐฐ์ด, ๊ฐ์ฒด ๋ชจ๋ ์ํ๊ฐ ๊ด๋ฆฌ ๊ฐ๋ฅ.
- setCar(previousState => {
return { ...previousState, color:"white" };
}
);- ** previousState ** ์ด ๋ถ๋ถ ์ค์!!
- ์ด์ ์ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ณ๊ฒฝ ํ ๋ --> ๊ผญ ์จ์ผํจ!!
- ๊ฐ์ฒด / ๋ฐฐ์ด state๋ ๊ธฐ๋ณธ์ ์ผ๋ก prev => ์ด๋ค๊ณ ์๊ฐํ๋ฉด ์์ ํ๋ค.!
- ** previousState ** ์ด ๋ถ๋ถ ์ค์!!
import { createRoot } from 'react-dom/client';
import { useState } from 'react';
function App() {
const [car, setCar] = useState({
brand : "ํ๋",
model : "์ ๋ค์์ค",
color : "black"
});
const updateCarInfo = () => {
setCar(previousState => {
return { ...previousState, color:"white" };
}
);
};
return (
<>
<p>{car.brand} {car.model} {car.color}</p>
<button onClick={updateCarInfo}>ํด๋ฆญ</button>
</>
);
}
createRoot(document.getElementById('react4')).render( <App /> );
๐ uesEffect ?
- ๋ฆฌ์กํธ ํจ์ํ ์ปดํฌ๋ํธ์์ side effects ๋ฅผ ์ํํ๊ธฐ ์ํ ํ .
- ๋๋๋ง์ ๋๋, ์ค์ DOM ์ ๋ฐ์ดํธ๋ ์๋ตํจ.
- state ์ ๊ฐ์ ๋ณํ๋ฅผ ๊ฐ์งํด์ ์๋ํจ.
- useEffect( () => {
console.log(`${count} useEffect ์คํ๋จ`);
}, [ ] );- ๋งจ ์ฒ์์ ๋ก๋(๋ง์ดํธ) ๋ ๋๋ ๋น์ฐํ ์คํ๋๊ณ .
state ๊ฐ์ด ๋ณํํ๋ฉด ์๋ํจ. - ๋ค์ ์๋ [] ์๋ ๋ณํ๋ฅผ ๊ฐ์งํ ๋ณ์์ ๋ํด์ ์ ์.
- ์ด ๋ฐฐ์ด์ ์ด๋ฆ?? --> ์์กด์ฑ ๋ฐฐ์ด
- ex) useEffect( () => {console.log(`${count} useEffect ์คํ๋จ`);}, [ count ] );
- ๋ผ๋ฉด --> count ๋ณ์๊ฐ์ ๋ณํ๋ง ๊ฐ์งํจ.
- ์ ๋ถ ๋ค ๊ฐ์งํ๋ฉด [] ๋ฅผ ์๋ต!
- ๋งจ ์ฒ์์ ๋ก๋(๋ง์ดํธ) ๋ ๋๋ ๋น์ฐํ ์คํ๋๊ณ .
- ํ ๊ธ ์ฌ์ฉํ๋ ๊ณต์ !!
- setState(prev => !prev);
- useEffect์ return์ “์ ๋ฆฌ(cleanup) ํจ์”๋ฅผ ๋ฑ๋กํ๋ ๊ฒ์ด๋ค.
- “์ด effect๊ฐ ๋๋๊ฑฐ๋, ๋ค์ ์คํ๋๊ธฐ ์ง์ ์, ๋๋ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ผ์ง ๋ ์ด ํจ์๋ฅผ ์คํํด๋ผ.”
- ์์กด์ฑ ๋ฐฐ์ด์ด ํ๋ ์ผ??
- ์์กด์ฑ ๋ฐฐ์ด = "์๋ ์กฐ๊ฑด"
- ๋ฆฌ์กํธ๋ ๋งค ๋ ๋๋ง ๋ง๋ค ์์กด์ฑ ๋ฐฐ์ด ์์ ๊ฐ์ด ๋ฐ๊ผ๋ ์ง ํ์ธํจ.
- ๋ฐ๊ผ์ผ๋ฉด --> cleanup --> effect ์ฌ์คํ.
- ์ ๋ฐ๊ผ์ผ๋ฉด --> ์๋ฌด๊ฒ๋ ์ํจ.
- 3๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํจ.
- [] ๋น ๋ฐฐ์ด
- ๋ฑ ํ ๋ฒ๋ง ์คํ๋๋ effect
- ์ด๋ฒคํธ ๋ฑ๋ก, ํ์ด๋จธ ์์, ์ด๊ธฐ ๋ฐ์ดํฐ ์์ฒญ ๋ฑ๋ฑ --> ์ด๊ธฐ 1ํ ์์ ์ ์ฐ์.
- “์ด effect๋ ์ด๋ค state / props ๋ณํ์๋ ์์กดํ์ง ์๋๋ค”
- ์คํ ํ์ด๋ฐ
- ์ฒ์ ํ๋ฉด ๋ฑ์ฅ (mount)
→ effect ์คํ
ํ๋ฉด์์ ์ฌ๋ผ์ง ๋ (unmount)
→ cleanup ์คํ
- ์ฒ์ ํ๋ฉด ๋ฑ์ฅ (mount)
- [value] (์์กด์ฑ ์์.)
- ๋ ๋๋ง ๋ฐ์. --> ์ด์ value ์ ๋น๊ตํด์ --> ๊ฐ์ด ๋ค๋ฅด๋ฉด effect ์คํ.
- ์คํ ํ๋ฆ
- ์ด๊ธฐ ๋ ๋ → effect
value ๋ณ๊ฒฝ
→ cleanup
→ effect ์ฌ์คํ
- ์ด๊ธฐ ๋ ๋ → effect
- ์์กด์ฑ ๋ฐฐ์ด ์๋ต.
- ์กฐ๊ฑด์ด ์์ผ๋ฉด?? --> ๋งค ๋ ๋๋ง๋ง๋ค ์คํํจ.
- ๊ฒฐ๊ณผ
- ๋ ๋๋ง๋ง๋ค effect ์คํ
๋ ๋๋ง๋ง๋ค cleanup ์คํ - --> ๋ด ์ฝ๋์์๋ ์์ํ์๋ง์ ๊บผ์ง ๊บผ์.
- ๋ ๋๋ง๋ง๋ค effect ์คํ
- [] ๋น ๋ฐฐ์ด
- ์์กด์ฑ ๋ฐฐ์ด = "์๋ ์กฐ๊ฑด"
import {createRoot} from 'react-dom/client';
import { useState, useEffect } from 'react';
import Counter from './Counter';
function App() {
const [count, setCount] = useState(0);
const [name, setName] = useState("");
const updateCounter = () => {
setCount(count + 1);
console.log("usestate ์คํ")
};
const handleNameChange = (e) => {
setName(e.target.value);
}
useEffect( () => {
console.log(`${count} count - useEffect ์คํ๋จ`);
}, [count]);
useEffect( () => {
console.log(`${name} name - useEffect ์คํ๋จ`);
}, [name]);
return (
<div>
<p>{count}</p>
<button onClick={updateCounter}>์นด์ดํธ ์ฆ๊ฐ</button>
<input type="text" onChange={handleNameChange} />
<p>{name}</p>
</div>
);
}
function App2() {
const [showCounter, setShowCounter] = useState(false);
return(
<>
{ showCounter && <Counter /> }
<button onClick={ () => {setShowCounter(prev => !prev)} }>ํด๋ฆญ</button>
</>
);
}
createRoot(document.getElementById('react4')).render( <App2 /> );
## Counter.jsx
import React, {useEffect, useState} from 'react';
const Counter = (props) => {
const [cnt, setCnt] = useState(0);
useEffect(() => {
const counter = setInterval( () => {
console.log(`${cnt} --- counter works`);
setCnt( cnt + 1 );
/* ์ ์์ ์ด๊ฑฐ!
effect ๋ ํ๋ฒ๋ง ํธ์ถํ๊ณ , cnt ๋ ์ฆ๊ฐํ๊ฒ ๋จ.
setCnt(prev => {
console.log(`${cnt} --- counter works -- ${prev} `);
return prev + 1;
});
*/
}, 1000);
return () => {
clearInterval(counter);
console.log("stop!12313!");
};
}, []);
return (
<div>
<p>counter is working!!</p>
</div>
)
}
export default Counter;
๐ ๋ด ์ฝ๋์์ ์์กด์ฑ ๋ฐฐ์ด์ด ์๊ณ ์๊ณ ์ ์ฐจ์ด?
- [] ๋น ๋ฐฐ์ด์ธ ๊ฒฝ์ฐ
- [Log] 0 --- counter works (Counter.jsx, line 9, x3)
[Log] stop!12313! (Counter.jsx, line 14) - count ๊ฐ 0๋ง ๋์ด.
- ๋น ๋ฐฐ์ด []์ด๋ฉด
useEffect๋ ์ฒ์ ํ ๋ฒ๋ง ์คํ๋๊ณ ,
interval์ ์ฒ์์ cnt = 0๋ง ๊ธฐ์ตํ ์ฑ ๊ณ์ ๋๋ค. - JS ํจ์๋ “๋ง๋ค์ด์ง ์๊ฐ์ ๋ณ์ ๊ฐ์ ๊ธฐ์ต”ํ๋ค. --> ์ด effect๊ฐ ์คํ๋ ๋น์์ cnt๋ฅผ ๊ธฐ์ตํด.

- ํด๋ก์ ๊ฐ ์ฒ์ ๊ฐ์ ๋ถ์ก๊ณ ์๊ธฐ ๋๋ฌธ.
- start / stop ์ ๋ฐ๋ณตํด๋ ๊ณ์ํด์ cnt = 0 ์ธ๋ฐ...
- ์ด๊ฑด cnt๊ฐ 1๋ถํฐ ์์ํ์ง ์๋ ์ด์ ๋
cleanup ํ์ “์ด์ interval์ด ์ฌ๊ฐ๋๋ ๊ฒ ์๋๋ผ”,
“์ปดํฌ๋ํธ๊ฐ ์๋ก ๋ง๋ค์ด์ง๋ฉด์ state์ effect๊ฐ ๋ค์ ์ด๊ธฐํ๋๊ธฐ ๋๋ฌธ”์ด์ผ. - ๊ฐ์ ์ปดํฌ๋ํธ์ ์ฌ์์ ์๋ !!!! โ โ
- โญ๏ธโญ๏ธ ์์ ํ ์ ์ธ์คํด์ค ์์ฑ. โญ๏ธ โญ๏ธ
- ์ปดํฌ๋ํธ๊ฐ ์ธ๋ง์ดํธ๋ ๋ ์ผ์ด๋๋ ์ผ.
- Counter ์ธ๋ง์ดํธ
↓
cleanup ์คํ
↓
interval ์ ๊ฑฐ
↓
์ปดํฌ๋ํธ ๋ฉ๋ชจ๋ฆฌ์์ ์ ๊ฑฐ
↓
state(cnt)๋ ํจ๊ป ์ฌ๋ผ์ง - โ ์ด ์์ ์ cnt = 1 ์ด์๋ค๊ณ ํด๋
๐ ๊ทธ ๊ฐ์ ํ๊ธฐ๋จ
- Counter ์ธ๋ง์ดํธ
- ์ "์ด์ cnt=1" ์ด ์ด์ด์ง์ง ์๋๊ฐ???
- ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ผ์ง๋ฉด → state๋ ์ฌ๋ผ์ง
- ๋ค์ ์๊ธฐ๋ฉด → ์ฒ์๋ถํฐ ๋ค์ ์์ฑ (--> cnt = 0)
- cleanup ์ดํ์ ๋ค์ ์์๋๋ ๊ฑด “์ด์ effect์ ์ฌ๊ฐ”๊ฐ ์๋๋ผ “์ ์ปดํฌ๋ํธ์ ์ฒซ ์คํ”์ด๋ค.
- ์ด์ state ์ ์งํ๊ณ ์ถ์ผ๋ฉด → ๋ถ๋ชจ๋ก ๋์ด์ฌ๋ ค์ผ ํจ
-
๋๋ณด๊ธฐ๋๋ณด๊ธฐ
function App() { const [cnt, setCnt] = useState(0); const [show, setShow] = useState(false); return ( <> <button onClick={() => setShow(p => !p)}>toggle</button> {show && <Counter cnt={cnt} setCnt={setCnt} />} </> ); }Counter ๊ฐ ์ฌ๋ผ์ ธ๋
cnt ๋ App ์ ๋จ์ ์์.
"์ ์ปดํฌ๋ํธ์ ์ฒซ ์คํ" ์ ํ ๋?
props ๋ฅผ ๊ฐ์ง๊ณ ์๋ก Counter ์ปดํฌ๋ํธ๋ฅผ ์์ํ๊ฒ ๋จ.
์ด Counter ์ปดํฌ๋ํธ ์์ useEffect ๊ฐ ๋ค์ด์๊ณ !
-
- ์ด๊ฑด cnt๊ฐ 1๋ถํฐ ์์ํ์ง ์๋ ์ด์ ๋
- [Log] 0 --- counter works (Counter.jsx, line 9, x3)
- ์๋ตํ ๊ฒฝ์ฐ
- [Log] 8 --- counter works (Counter.jsx, line 9)
[Log] stop!12313! (Counter.jsx, line 14) - count ๊ฐ ๋์ด๋จ.
- ์์กด์ฑ ๋ฐฐ์ด์ ์๋ตํ๋ฉด
useEffect๊ฐ ๋งค ๋ ๋๋ง๋ง๋ค ๋ค์ ์คํ๋๊ณ ,
๊ทธ๋๋ง๋ค ์ต์ cnt๋ฅผ ์บก์ฒํ ์๋ก์ด interval์ด ๋ง๋ค์ด์ง๋ค. - ๋ ๋๋ง๋ง๋ค effect ๋ฅผ ๋ค์ ์คํํจ.
- cnt ๋ useEffect ๋ฐ์ ์์ผ๋๊น, useState๋ก ๋ณํ๊ฐ์ ๋ณผ ์ ์์์.

- start / stop ์ ์ฌ๋ฌ๋ฒ ๋๋ฌ์ ๋ณด๋ฉด, Interval ์ ํ ๋๋ cnt ๊ฐ์ด ์ฆ๊ฐํจ.
- ๊ทผ๋ฐ, stop ํ์ ๋ค์ start ํด๋ณด๋ฉด, ์์ ํ ์ด๊ธฐ๋ก ๋์๊ฐ --> cnt = 0 ์ผ๋ก ์๋ก ์์ํจ.
- [Log] 8 --- counter works (Counter.jsx, line 9)
๐ ?
- ใ ใ
๐ ?
- ใ ใ
์ถ์ฒ :
๊ฐ๋ฐ ๊ณต๋ถ๋ฅผ ์ํ ๋ธ๋ก๊ทธ ์ ๋๋ค.
์ค๋ฅ๊ฐ ์๋ค๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์ธ์!
๊ฐ์ฌํฉ๋๋ค.

728x90
'front > react' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [react] React Hook 3 (useReducer) (0) | 2026.01.07 |
|---|---|
| [react] React Hook 2 (useContext, useRef) (0) | 2026.01.06 |
| [react] React Transition (useTransition) (0) | 2026.01.04 |
| [react] React Router (BrowserRouter, Routes, Route, Link, Outlet, useParams) (0) | 2026.01.04 |
| [react] css ์ฌ์ฉ ๊ด๋ จ (inline css, css obj, import css, import css module, composes, global css className) (1) | 2026.01.02 |
