DOM์ ์ง์ ์กฐ์ํ๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ด๋ค. React๋ JSX ๋ฌธ๋ฒ์ผ๋ก ์ด๋ฃจ์ด์ง ์ฝ๋๋ก ๊ฐ์ DOM์ ์์ฑํ์ฌ ์ค์ DOM์ ๋ณ๊ฒฝ์ฌํญ์ ๋ฐ์ํ๋ค. ์ด๋ ๊ฒ ํจ์ผ๋ก์จ ๋ถํ์ํ ๋ ๋๋ง์ ์ค์ผ ์ ์๋๋ฐ ์ด ๊ฐ์ DOM์ ๋ง๋ค ๋ ์ํ ๊ฐ ๋ณํ์ ๋ฐ๋ผ ์ปดํฌ๋ํธ๊ฐ ์ฌ๊ตฌ์ฑ๋๊ณ ๋ฆฌ๋ ๋๋ง์ด ์ด๋ฃจ์ด์ง๋ค.
๊ณ ๋ก ์ํ ๊ด๋ฆฌ๋ ๋งค์ฐ ์ค์ํ๋ฉฐ hook๊ณผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด์ ๋ค์ํ๊ฒ ๊ด๋ฆฌํ ์ ์๋ค. ์๋ง์ ์ํ๊ด๋ฆฌ ๋ฐฉ๋ฒ ์ค์ ๊ธฐ์ด๋ผ๊ณ ํ ์ ์๋ useState์ useReducer ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํ๋ฉด์ ์ดํดํด๋ณด์.
import React, { useState } from 'react';
const App = () => {
const [cart, setCart] = useState(0); // ๋ฐฐ์ด ๋น๊ตฌ์กฐํ ํ ๋น
const onAddHandler = () => {
if(cart > 10) {
alert('10๊ฐ ์ด์์ ์ถ๊ฐํ ์ ์์ต๋๋ค.');
return;
}
setCart(prevCart => prevCart + 1);
}
return (
<div>
<div>์ฅ๋ฐ๊ตฌ๋ ๋ฌผํ {cart}๊ฐ</div>
<button onClick={onAddHandler}>์ถ๊ฐ</button>
</div>
);
};
๐ง state ์ ๋ฐ์ดํธ์ prevCart์ ์๋ฏธ๋?
state as snapshot์ ์๋ฏธํ๋ค. React๊ฐ state ๊ฐ์ ๋ณ๊ฒฝํ ๋ ๊ฐ์ฅ ์ต์ ์ state๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ ๋ฐ์ดํธ๋ฅผ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉ๋๋ ๊ฐ๋ ์ด๋ผ๊ณ ํ ์ ์๋ค.
reducer๊ด๋ จ ๊ฐ๋ | ๋ด์ฉ |
---|---|
reducer | ํ์ฌ state์ action์ ๋ ๊ฐ์ ์ธ์๋ก ๋ฐ์ ์๋ก์ด ์ํ๋ฅผ ๋ฐํํ๋ ํจ์ dispatch๊ฐ ์ ๋ฌํ ์ก์ ๊ฐ์ฒด์ ๋ฐ๋ผ ์ํ๋ฅผ ์ ๋ฐ์ดํธ (state, action) => newState์ ํํ |
์ด๊ธฐ ์ํ๊ฐ | ์ฒ์์ ์ค์ ํด์ฃผ๋ ๊ฐ |
์ด๊ธฐ ํจ์ | ์ด๊ธฐ state๋ฅผ ์ง์ฐํด์ ์์ฑ |
dispatch | ์ปดํฌ๋ํธ ๋ด์ ์ํ๋ฅผ ์
๋ฐ์ดํธํ๊ธฐ ์ํด ์ฌ์ฉ reducer์ ์ก์ ๊ฐ์ฒด๋ฅผ ๋๊น |
import React, { useReducer } from 'react';
// ์ด๊ธฐ๊ฐ
const initialState = { cart: 0 };
// reducer ํจ์
const reducer = (state, action) => {
switch(action.type){
case 'ADDCART':
if(cart > 10) {
throw new Error('10๊ฐ ์ด์์ ์ถ๊ฐํ ์ ์์ต๋๋ค.');
}
return { cart: state.cart + 1 };
}
};
// App ์ปดํฌ๋ํธ
const App = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const onAddHandler = () => dispatch({ type: 'ADDCART' });
return (
<div>
<div>์ฅ๋ฐ๊ตฌ๋ ๋ฌผํ {state.cart}๊ฐ</div>
<button onClick={onAddHandler}>์ถ๊ฐ</button>
</div>
)
}
์์ ๋์ผํ ๋ก์ง์ useState์ useReducer๋ก ์์ฑํด๋ณด์๋ค. ์ฌ์ค ๊ฐ๋จํ ๋ก์ง์ด๊ธฐ์ ์ด๋ป๊ฒ ๋ณด๋ฉด useState๋ก๋ง ์์ฑ์ ํด๋ ๋๋ค. ํ์ง๋ง ์ด์ ์ ์ ์ ๋ฐฐ์ ํ๊ณ ์ฝ๋๋ฅผ ์ดํด๋ณด์.
// useState๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ
const onAddHandler = () => {
if(cart > 10) {
throw new Error('10๊ฐ ์ด์์ ์ถ๊ฐํ ์ ์์ต๋๋ค.');
}
setCart(prevCart => prevCart + 1);
}
// useReducer๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ
const onAddHandler = () => dispatch({ type: 'ADDCART' });
const onAddHandler = () => dispatch({ type: 'ADDCART' });
const onDeleteHandler = () => dispatch({ type: 'DELETECART' });
๋น์ฆ๋์ค ๋ก์ง์ด ํจ์ฌ ๋ ๊ธธ์ด์ง๊ณ ํ๋ก์ ํธ์ ๊ท๋ชจ๊ฐ ํด ๊ฒฝ์ฐ useReducer๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๊ฒฐํ๊ณ ์ด๋ค ๋ก์ง์ ์คํํ๊ณ ์๋์ง ํ๋์ ํ์
ํ ์ ์์ผ๋ฉฐ ์ผ๊ด์ฑ์๊ฒ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
๐จ ๊ฐ์ฅ ์ค์ํ ์ ์ ๊ฐ๋ฐ ์ํฉ์ ๋ง๊ฒ hooks๋ฅผ ์ฌ์ฉํด์ผํ๋ค๋ ๊ฒ์ด๋ค!!!
์ค๋์ useReducer์ ํ์์ฑ์ ์ ๋ฆฌํ ์ ์์๋ ์๊ฐ.
์ํ๋ฅผ ๊ฐ๊ณตํ์ฌ setter ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ด ์ํ๋ฅผ ๊ฐ๊ณตํ๋ ๋ก์ง์ด ๋ณต์กํ๋ฉด useReducer๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์ฌ ์ฝ๋์ ๊ฐ๋
์ฑ์ ๋์ผ ์ ์์๋ค. ์ปดํฌ๋ํธ์์ dispatch ํจ์์ ํ์
์ผ๋ก ํด๋น ๋น์ฆ๋์ค ๋ก์ง์ด ์ด๋ค ์ญํ ์ ํ๋์ง ํ์
์ ํ ์ ์์๋ค.
์ด๋ฐ ์ฐจ์ด์ ์ ์๊ณ ์ฝ๋๋ฅผ ๊ตฌํํ๋๋ก ํด์ผ๊ฒ ๋ค.
์ฐธ๊ณ ์๋ฃ
https://cpro95.tistory.com/m/642
https://react.vlpt.us/basic/07-useState.html
https://velog.io/@tnsdlf158/React-Hooks-useReducer