1. ์ปดํฌ๋ํธ์ ๋ผ์ดํ ์ฌ์ดํด ๋ฉ์๋
2. Hooks์ ์ข
๋ฅ
3. useMemo vs. useCallBack
4. setState๋ ๋น๋๊ธฐ
1. ์ปดํฌ๋ํธ์ ๋ผ์ดํ ์ฌ์ดํด ๋ฉ์๋ โญ๏ธโญ๏ธ
- will~ ๋ฉ์๋: ์ด๋ค ์์
์ ์๋ํ๊ธฐ ์ ์ ์คํ๋๋ ๋ฉ์๋
- Did~ ๋ฉ์๋: ์ด๋ค ์์
์ ์๋ํ ํ์ ์คํ๋๋ ๋ฉ์๋
- ๋ฉ์๋๋ ์ปดํฌ๋ํธ ํด๋์ค์์ ๋ฎ์ด ์จ ์ ์ธํจ์ผ๋ก์จ ์ฌ์ฉํ ์ ์์
- ๋ผ์ดํ์ฌ์ดํด์ ์ด ์ธ ๊ฐ์ง, ์ฆ ๋ง์ดํธ, ์
๋ฐ์ดํธ, ์ธ๋ง์ดํธ ์นดํ
๊ณ ๋ฆฌ๋ก ๋๋
- ๋ง์ดํธ โญ๏ธ
- DOM์ด ์์ฑ๋๊ณ ์น ๋ธ๋ผ์ฐ์ ์์ ๋ํ๋๋ ๊ฒ์ ๋ง์ดํธ๋ผ๊ณ ํจ
- componentDidMount: ์ปดํฌ๋ํธ๊ฐ ์น ๋ธ๋ผ์ฐ์ ์์ ๋ํ๋ ํ ํธ์ถํ๋ ๋ฉ์๋
- ์
๋ฐ์ดํธ โญ๏ธ
- ์ปดํฌ๋ํธ๋ ๋ค์๊ณผ ๊ฐ์ ๋ค ๊ฐ์ง ๊ฒฝ์ฐ ์
๋ฐ์ดํธ
- Props๊ฐ ๋ฐ๋ ๋
- state๊ฐ ๋ฐ๋ ๋
- ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋ ๋
- this.forceUpdate๋ก ๊ฐ์ ๋ก ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํ ๋
- componentDidUpdate: ์ปดํฌ๋ํธ์ ์ ๋ฐ์ดํธ(๋ฆฌ๋ ๋๋ง) ์์ ์ด ๋๋ ํ ํธ์ถํ๋ ๋ฉ์๋
- ์ปดํฌ๋ํธ๋ ๋ค์๊ณผ ๊ฐ์ ๋ค ๊ฐ์ง ๊ฒฝ์ฐ ์
๋ฐ์ดํธ
- ์ธ๋ง์ดํธ โญ๏ธ
- ๋ง์ดํธ์ ๋ฐ๋ ๊ณผ์ , ์ฆ ์ปดํฌ๋ํธ๋ฅผ DOM์์ ์ ๊ฑฐํ๋ ๊ฒ
- componentWillUnmount: ์ปดํฌ๋ํธ๊ฐ ์น ๋ธ๋ผ์ฐ์ ์์ ์ฌ๋ผ์ง๊ธฐ ์ ์ ํธ์ถํ๋ ๋ฉ์๋
2. Hooks์ ์ข ๋ฅ โญ๏ธโญ๏ธ
- Hooks๋ ๋ฆฌ์กํธ ๋ฒ์ 16.8์ ์๋ก ๋์
๋ ๊ธฐ๋ฅ์ผ๋ก ํจ์ ์ปดํฌ๋ํธ์์๋ ์ํ ๊ด๋ฆฌ๋ฅผ ํ ์ ์๋ useState ๋ ๋๋ง ์งํ ์์
์ ์ค์ ํ๋ useEffect ๋ฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๊ธฐ์กด์ ํจ์ ์ปดํฌ๋ํธ์์ ํ ์ ์์๋ ๋ค์ํ ์์
์ ํ ์ ์๊ฒ ํด์ค
- useState
- ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ Hook, ์ฒซ ๋ฒ์งธ ์์๋ ์ํ ๊ฐ, ๋ ๋ฒ์งธ ์์๋ ์ํ๋ฅผ ์ค์ ํ๋ ํจ์
- ์ด ํจ์์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฃ์ด์ ํธ์ถํ๋ฉด ์ ๋ฌ๋ฐ์ ํ๋ผ๋ฏธํฐ๋ก ๊ฐ์ด ๋ฐ๋๊ณ ์ปดํฌ๋ํธ๊ฐ ์ ์์ ์ผ๋ก ๋ฆฌ๋ ๋๋ง ๋จ
import { useState } from 'react';
const [value, setValue] = useState(0);
/* useState ๋ด๋ถ์ ๋ชจ์ต์ ๊ตฌํํ ๋ชจ์ต */
const MyReact = (function () {
const global = {};
let index = 0;
function useState(initialState) {
if (!global.states) {
// ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒด์ states ๋ฐฐ์ด์ ์ด๊ธฐํํ๋ค.
// ์ต์ด ์ ๊ทผ์ด๋ผ๋ฉด ๋น ๋ฐฐ์ด๋ก ์ด๊ธฐํํ๋ค.
global.states = [];
}
// states ์ ๋ณด๋ฅผ ์กฐํํด์ ํ์ฌ ์ํ๊ฐ์ด ์๋์ง ํ์ธํ๊ณ ์๋ค๋ฉด ์ด๊น๊ฐ์ผ๋ก ์ค์ ํ๋ค.
const currentState = global.states[index] || initialState;
// states์ ๊ฐ์ ์์์ ์กฐํํ ํ์ฌ ๊ฐ์ผ๋ก ์
๋ฐ์ดํธํ๋ค.
global.states[index] = currentState;
// ์ฆ์ ์คํ ํจ์๋ก setter๋ฅผ ๋ง๋ ๋ค.
const setState = (function () {
// ํ์ฌ index๋ฅผ ํด๋ก์ ๋ก ๊ฐ๋ฌ๋์ ์ดํ์๋ ๊ณ์ํด์ ๋์ธํ index์ ์ ๊ทผํ ์ ์๋๋ก ํ๋ค.
let currentIndex = index;
return function (value) {
global.states[currentIndex] = value;
// ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋ค. ์ค์ ๋ก ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋ ์ฝ๋๋ ์๋ตํ๋ค.
};
})();
/**
* useState๋ฅผ ์ธ ๋๋ง๋ค index๋ฅผ ํ๋์ฉ ์ถ๊ฐํ๋ค. ์ด index๋ setState์์ ์ฌ์ฉ๋๋ค.
* ์ฆ, ํ๋์ state๋ง๋ค index๊ฐ ํ ๋น๋ผ ์์ด ๊ทธ index๊ฐ ๋ฐฐ์ด์ ๊ฐ(global.states)์ ๊ฐ๋ฆฌํค๊ณ ํ์ํ ๋๋ง๋ค ๊ทธ ๊ฐ์ ๊ฐ์ ธ์ค๊ฒ ํ๋ค.
**/
index = index + 1;
return [currentState, setState];
}
function Component() {
const [value, setValue] = useState(0);
//...
return <div>{value}</div>;
}
})();
- useEffect
- ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ ๋๋ง๋ค ํน์ ์์ ์ ์ํํ๋๋ก ์ค์ ํ ์ ์๋ Hook
- ํด๋์คํ ์ปดํฌ๋ํธ์ componentDidMount์ componentDidUpdate๋ฅผ ํฉ์น ํํ๋ก ๋ณด์๋ ๋ฌด๋ฐฉ
- useEffect๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ๋๋ง๋๊ณ ๋ ์งํ๋ง๋ค ์คํ๋๋ฉฐ ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ ๋ฐฐ์ด์ ๋ฌด์์ ๋ฃ๋์ง์ ๋ฐ๋ผ ์คํ๋๋ ์กฐ๊ฑด์ด ๋ฌ๋ผ์ง
- ์ปดํฌ๋ํธ๊ฐ ์ธ๋ง์ดํธ ์ ์ด๋ ์ ๋ฐ์ดํธ๋๊ธฐ ์ง์ ์ ์ด๋ ํ ์์ ์ ์ํํ๊ณ ์ถ๋ค๋ฉด useEffect์์ ๋ท์ ๋ฆฌ(cleanup)ํจ์๋ฅผ ๋ฐํํด ์ฃผ์ด์ผ ํจ
/* ๋ง์ดํธ๋ง ์คํ์ํค๊ณ ์ถ์ ๊ฒฝ์ฐ: ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก ๋น์ด์๋ ๋ฐฐ์ด์ ๋ฃ์ด์ฃผ๋ฉด ๋จ */
useEffect(() => {
console.log('๋ง์ดํธ๋ ๋๋ง ์คํ๋ฉ๋๋ค.');
}, []);
/* ํน์ ๊ฐ์ด ์
๋ฐ์ดํธ๋ ๋๋ง ์คํํ๊ณ ์ถ์ ๊ฒฝ์ฐ: ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋๋ ๋ฐฐ์ด ์์ ๊ฒ์ฌํ๊ณ ์ถ์ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๋จ */
useEffect(() => {
console.log(name);
}, [name]);
/* ๋ท์ ๋ฆฌ(cleanup)์ฝ๋ */
useEffect(() => {
console.log("๋ ๋๋ง์ด ์๋ฃ๋์์ต๋๋ค!");
console.log("none clean up: ", { name, nickname });
return () => {
console.log("clean up!");
console.log("clean up name: ", { name });
};
}
- useReducer
- useState๋ณด๋ค ๋ ๋ค์ํ ์ปดํฌ๋ํธ ์ํฉ์ ๋ฐ๋ผ ๋ค์ํ ์ํ๋ฅผ ๋ค๋ฅธ ๊ฐ์ผ๋ก ์ ๋ฐ์ดํธํด ์ฃผ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ Hook
- ํ์ฌ ์ํ, ๊ทธ๋ฆฌ๊ณ ์ ๋ฐ์ดํธ๋ฅผ ์ํด ํ์ํ ์ ๋ณด๋ฅผ ๋ด์ ์ก์ ๊ฐ์ ์ ๋ฌ๋ฐ์ ์๋ก์ด ์ํ์ ๋ฐํํ๋ ํจ์
- ๋ฆฌ๋์ ํจ์์์ ์๋ก์ด ์ํ๋ฅผ ๋ง๋ค ๋๋ ๋ฐ๋์ ๋ถ๋ณ์ฑ์ ์ง์ผ์ค์ผ ํจ
- ์ฆ, ๋ณต์กํ ํํ์ state๋ฅผ ์ฌ์ ์ ์ ์๋ dispatcher๋ก๋ง ์์ ํ ์ ์๊ฒ ๋ง๋ค์ด ์ค์ผ๋ก์จ state ๊ฐ์ ๋ํ ์ ๊ทผ์ ์ปดํฌ๋ํธ์์๋ง ๊ฐ๋ฅํ๊ฒ ํ๊ณ , ์ด๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ธ ์ ์๋ ์ปดํฌ๋ํธ ๋ฐ์ ๋ ๋ค์, state์ ์ ๋ฐ์ดํธ๋ฅผ ๋ฏธ๋ฆฌ ์ ์ํด ๋ dispatcher๋ก๋ง ์ ํํ๋ ๊ฒ
- state์ ๊ฐ์ ๋ณ๊ฒฝํ๋ ์๋๋ฆฌ์ค๋ฅผ ์ ํ์ ์ผ๋ก ๋๊ณ ์ด์ ๋ํ ๋ณ๊ฒฝ์ ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์๊ฒ๋ ํ๋ ๊ฒ์ด ๋ชฉ์ !
type State = {
count: number,
};
type Action = { type: 'up' | 'down' | 'reset', payload?: State };
function init(count: State): State {
return count;
}
const initialState: State = { count: 0 };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'up':
return { count: state.count + 1 };
case 'down':
return { count: state.count - 1 };
case 'reset':
return init(action.payload || { count: 0 });
default:
throw new Error(`Unexpected action type ${action.type}`);
}
}
export default function App() {
const [state, dispatcher] = useReducer(reducer, initialState, init);
function handleUpButtonClick() {
dispatcher({ type: 'up' });
}
function handleDownButtonClick() {
dispatcher({ type: 'down' });
}
function handleResetButtonClick() {
dispatcher({ type: 'reset', payload: { count: 1 } });
}
return (
<div>
<h1>{state.count}</h1>
<button onClick={handleDownButtonClick}>+</button>
<button onClick={handleDownButtonClick}>-</button>
<button onClick={handleResetButtonClick}>reset</button>
</div>
);
}
- useMemo
- ํจ์ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ๋ฐ์ํ๋ ์ฐ์ฐ ์ต์ ํ
- ๋ ๋๋งํ๋ ๊ณผ์ ์์ ํน์ ๊ฐ์ด ๋ฐ๋์์ ๋๋ง ์ฐ์ฐ์ ์คํํ๊ณ , ์ํ๋ ๊ฐ์ด ๋ฐ๋์ง ์์๋๋ฉด ์ด์ ์ ์ฐ์ฐํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ์ฌ์ฉํ๋ ๋ฐฉ์
import React, { useCallback, useMemo, useRef, useState } from 'react';
const getAverage = (numbers) => {
console.log('ํ๊ท ๊ฐ ๊ณ์ฐ ์ค..');
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const inputEl = useRef();
const onChange = useCallback((e) => {
setNumber(e.target.value);
}, []); // ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ๋ ๋๋ง๋ ๋๋ง ํจ์ ์์ฑ
const onInsert = useCallback(
(e) => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
inputEl.current.focus();
},
[number, list] // number ํน์ list๊ฐ ๋ฐ๋์์ ๋๋ง ํจ์ ์์ฑ
);
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} ref={inputEl} />
<button onClick={onInsert}>๋ฑ๋ก</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>ํ๊ท ๊ฐ:</b> {avg}
</div>
</div>
);
};
export default Average;
- useCallback
- useMemo์ ์๋นํ ๋น์ทํ ํจ์๋ก ๋ง๋ค์ด๋จ๋ ํจ์๋ฅผ ์ฌ์ฌ์ฉํ ์ ์์
- ์ฒซ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ์์ฑํ๊ณ ์ถ์ ํจ์๋ฅผ ๋ฃ๊ณ , ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์๋ ๋ฐฐ์ด์ ๋ฃ์, ์ด ๋ฐฐ์ด์๋ ์ด๋ค ๊ฐ์ด ๋ฐ๋์์ ๋ ํจ์๋ฅผ ์๋ก ์์ฑํด์ผ ํ๋์ง ๋ช ์ํด์ผ ํจ
- ์ฃผ๋ก ๋ ๋๋ง ์ฑ๋ฅ์ ์ต์ ํ ํด์ผํ๋ ์ํฉ์์ ์ฌ์ฉ
const onChange = useCallback((e) => {
setNumber(e.target.value);
}, []); // ์ปดํฌ๋ํธ๊ฐ ์ฒ์ ๋ ๋๋ง๋ ๋๋ง ํจ์ ์์ฑ
const onInsert = useCallback(
(e) => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
},
[number, list] // number ํน์ list๊ฐ ๋ฐ๋์์ ๋๋ง ํจ์ ์์ฑ
/* ํจ์ ๋ด๋ถ์์ ์ํ ๊ฐ์ ์์กดํด์ผ ํ ๋๋ ๊ทธ ๊ฐ์ ๋ฐ๋์ ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ ์์ ํฌํจ์์ผ ์ฃผ์ด์ผ ํจ */
);
useMemo(() => {
const fn = () => {
console.log(‘hello world!‘);
};
return fn;
}, [])
- useRef
- ๋ฐ๋๋ผ ์๋ฐ์คํฌ๋ฆฝํธ์์ DOM ์์๋ฅผ ์กฐ์ํ๊ธฐ ์ํด querySelector๋ getElementById ๋ฑ์ ์ฌ์ฉํ๋ค๋ฉด, ๋ฆฌ์กํธ์์๋ useRef ํ ํจ์๋ฅผ ์ฌ์ฉํจ
- .current ํ๋กํผํฐ์ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ๊ฐ์ ๋ด๊ณ ์๋ ๊ฐ์ฒด์
- .current ํ๋กํผํฐ๋ฅผ ๋ณ๊ฒฝํ๋๋ผ๋ ๋ฆฌ๋ ๋๋ง์ ์ ๋ฐํ์ง ์์. ref ๊ฐ์ฒด ์์ ๊ฐ์ ๋ฆฌ์กํธ ์๋ช ์ฃผ๊ธฐ์ ๋ ๋ฆฝ์ ์ด๊ธฐ ๋๋ฌธ
import React, { useRef, Component } from 'react';
class RefSample extends Component {
input = useRef();
handleFocus = () => {
this.input.current.focus();
};
render() {
return (
<div>
<input ref={input} />
</div>
);
}
}
export default RefSample;
- Q) ์ธ์ useState ๋์ useRef๋ฅผ ์ฌ์ฉํ ์ ์๋์?
- A) useRef๋ ๊ตฌ์ฑ์์๊ฐ ๋ณ๊ฒฝ๋ ๋ ์ฌ๋ ๋๋ฅผ ํธ๋ฆฌ๊ฑฐํ์ง ์์์ผ ํ๋ ๊ฐ์ ์ ์ฅํด์ผ ํ ๋ ์ฌ์ฉํด์ผ ํจ. ๋ฐ๋ฉด, useState๋ ๊ตฌ์ฑ ์์๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋ค์ ๋ ๋๋ง์ ํธ๋ฆฌ๊ฑฐํด์ผ ํ๋ ๊ฐ์ ์ ์ฅํด์ผ ํ ๋ ์ฌ์ฉ.
๋ฐ๋ผ์ ํ๋ฉด์ ์ผ๋ถ ๋ด์ฉ์ ํ์ํ์ง ์๋ ๊ฒฝ์ฐ, ๋ ๋๋ง์ ์ํฅ์ ๋ฐ์ง ์์๋ ๋๋ ๊ฒฝ์ฐ์ useRef๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ฆฌ๋ ๋๋ง์ ์กฐ๊ธ ๋ ํจ์จ์ ์ผ๋ก ํธ๋ค๋ง ํ ์ ์์.
3. useMemo vs. useCallBack โญ๏ธโญ๏ธ
- useMemo ํจ์๋ ๋ฉ๋ชจ์ด์ ์ด์ ๋ ๊ฐ์ ๋ฐํ
- useCallBack ํจ์๋ ๋ฉ๋ชจ์ด์ ์ด์
๋ ํจ์๋ฅผ ๋ฐํ
- Memoization(๋ฉ๋ชจ์ด์ ์ด์ ): ํ๋ก๊ทธ๋จ ์คํ ์ ์ด์ ์ ๊ณ์ฐํ ๊ฐ์ ์ ์ฅํจ. ์ํ์ง ๊ฐ์ด ๋ฐ๋์ง ์์๋ค๋ฉด ์ด์ ์ ์ฐ์ฐํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ์ฌ์ฉ
- ์ปดํฌ๋ํธ๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ๋ฆฌ๋ ๋๋ง ๋๋๋ฐ,
1. props๊ฐ ๋ฐ๋ ๋
2. state๊ฐ ๋ฐ๋ ๋
3. ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋ ๋ - ์ด๋ฐ ํน์ ์ํฉ(๊ฐ, ๋๋ ํจ์๊ฐ ๋ณ๊ฒฝ๋ ๋)์ ๋ง๊ฒ ๋ฆฌ๋ ๋๋ง์ด ๋ ์ ์๋๋ก useMemo์ useCallBack ํจ์๋ฅผ ์ฌ์ฉํจ
- ์์กด์ฑ ๋ฐฐ์ด๋ก ์ด๋ค ๊ฐ์ ์ํด ๋ฐ๋๋ ์ง ํ์ธํ๊ธฐ ์ํด์๋ ํด๋น ํจ์์ ๋ ๋ฒ์งธ ์ฝ๋ฐฑ์ธ [] ๋ฐฐ์ด ๋ด๋ถ์ ๊ฐ์ ๋ณด๋ฉด ๋จ
// useMemo
const avg = useMemo(() => getAverage(list), [list]); // list ๋ผ๋ ๊ฐ์ด ๋ณ๊ฒฐ๋ ๋'๋ง' getAverage ํจ์๋ฅผ ์ฌ ํธ์ถํ๋ ์ฉ๋์
๋๋ค
// useCallback
const onInsert = useCallback(
(e) => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
},
[number, list] // number ํน์ list๊ฐ ๋ฐ๋์์ ๋๋ง onInsert ํจ์ ์์ฑ
);
// useMemo
<div>
<b>ํ๊ท ๊ฐ:</b> {avg}
</div>
// useCallback
<button onClick={onInsert}>๋ฑ๋ก</button>
- Q) useCallBack์ ์ฌ์ฉํ ๋์ ์ฌ์ฉํ์ง ์๊ณ ํจ์๋ฅผ ์ ์ธํ ๋๋ ์ด๋ค ์ฐจ์ด๊ฐ ์๋์?
- A) useCallBack ํ
ํจ์๋ ๋ฉ๋ชจ์ด์ ์ด์
์ ํ ์ ์๋๋ก ํ์ฉํ๋ ๋ฆฌ์กํธ์ ํ
์. ์ฆ, ์ข
์์ฑ ์ค ํ๋๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ์๋ง ํจ์๊ฐ ๋ค์ ์์ฑ๋จ. ์ด ๊ธฐ๋ฅ์ ๊ตฌ์ฑ ์์๊ฐ ์์ฃผ ๋ ๋๋ง๋๊ณ ํด๋น ๊ธฐ๋ฅ์ ์ฌ์์ฑํ๋ ๋ฐ ๋น์ฉ์ด ๋ง์ด ๋๋ ์ํฉ์์ ์ฑ๋ฅ ์ต์ ํ์ ์ ์ฉํ ์ ์์.
์ด์ ๋ฐ๋๋ก useCallBack์ ์ฌ์ฉํ์ง ์๊ณ ํจ์๋ฅผ ์ ์ธํ๋ ๊ฒฝ์ฐ ๋งค ๋ ๋๋ง๋ง๋ค ํจ์๋ฅผ ์๋กญ๊ฒ ์ ์ธํจ
ํจ์ ์ด๊ธฐํ(์ ์ธ, initialize) ๊ธฐ๋ฅ๊ณผ ํจ๊ป 'useCallBack' ํจ์๋ฅผ ์ฌ์ฉํ ์ง ์ฌ๋ถ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ์๊ตฌ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง
๊ธฐ๋ฅ์ด ๋น๊ต์ ๊ฐ๋จํ๊ณ ์ฌํ ๋น์ฉ์ด ๋ง์ด ๋ค์ง ์๋๋ค๋ฉด 'useCallback'์ ์ฌ์ฉํ ํ์๊ฐ ์์ ์๋ ์์
๊ทธ๋ฌ๋ ํจ์๋ฅผ ๋ค์ ๋ง๋๋ ๊ฒ์ด ๋ ๋ณต์กํ๊ฑฐ๋ ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ฒฝ์ฐ์๋ ์ด ํจ์์ ํจ๊ป 'useCallBack'์ ์ฌ์ฉํ๋ฉด ์์ฉ ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ์ ํฅ์์ํค๋ ๋ฐ ๋์์ด ๋ ์ ์์
4. ๋ฆฌ์กํธ์์ setState๋ ๋๊ธฐ์ธ๊ฐ ๋น๋๊ธฐ์ธ๊ฐ โญ๏ธ
function Example() {
const [count, setCount] = React.useState(0);
useEffect(()=>{
console.log('in useEffect:', count)
},[count])
const onClickButton = () => {
console.log("before", count);
setCount(count + 1);
// setCount(prev => prev+1);
console.log("after", count);
};
return <button onClick={onClickButton}>{count}</button>;
}
>>>
/*
before 0
after 0
in useEffect 1
*/
- state ๊ฐ์ ๊ฐฑ์ ํ๋ ํจ์์ธ setState๋ ๋น๋๊ธฐ๋ก ๋์ํ๋ ํ ํจ์์
- ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐ์์ ๋๋นํ๊ธฐ ์ํด ๋ฆฌ์กํธ๋ setState๋ฅผ ๋น๋๊ธฐ ํจ์๋ก ์ฒ๋ฆฌํด ์ปดํฌ๋ํธ ๋ด์ ๋น๋๊ธฐ ํจ์๋ฅผ ์ฒ๋ฆฌํ๋ ์ฝ๋ฐฑํ๊ฐ ๋ค ๋น์์ง๋ฉด ๋ฆฌ๋ ๋๋งํ๋๋ก ์ค๊ณ
- ์ฆ, ํด๋น ํจ์ ๋ด์์ ๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ ํจ์๊ฐ ๋ชจ๋ ์คํ๋ ๋ค์ ๋ง์ง๋ง์ setState๋ฅผ ์ฒ๋ฆฌ
const onClickButton = () => {
console.log('before', count); // ----> ๋๊ธฐํจ์
setCount(count + 1); // ----> ๋น๋๊ธฐํจ์
console.log('after', count); // ----> ๋๊ธฐํจ์
};
- Q) setState๊ฐ ๋น๋๊ธฐ ๋์์ ์ทจํ์ ๋ ์ป์ ์ ์๋ ์ด์ ์? โญ๏ธ
- A) setState๊ฐ ๋น๋๊ธฐ ๋์์ ์ทจํจ์ผ๋ก์จ ์๋ฐ์คํฌ๋ฆฝํธ ๋ด์ ์คํ์ปจํ
์คํธ ์คํ์ด ๋์๊ฐ ๋ ๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ ํจ์๋ค์ ๋ชจ๋ ๋์ํ ๋ค์ ํ์ ์กด์ฌํ๋ ๋น๋๊ธฐ์ ์ธ ํจ์๋ค์ ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ๊บผ๋ด์์ ์คํ์ํด.
setState๊ฐ ๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ค๋ฉด, ํ ์ปดํฌ๋ํธ ๋ด๋ถ์ ์กด์ฌํ๋ ํจ์์ ์ํด state ๊ฐ์ด ์ฐ์์ ์ผ๋ก ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ๋ฆฌ์กํธ์ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง ์กฐ๊ฑด์ ์ํด ์ง์์ ์ผ๋ก ๋ฆฌ๋ ๋๋ง์ด ๋ ๊ฒ์.