숫자를 count하는 기능을 만들어보자!
export default function App() {
const [count, setCount] = useState(0);
function down() {
setCount(count - 1);
}
function reset() {
setCount(0);
}
function up() {
setCount(count + 1);
}
return (
<div>
<input type="button" value="-" onClick={down} />
<input type="button" value="0" onClick={reset} />
<input type="button" value="+" onClick={up} />
<span>{count}</span>
</div>
);
}
이 기능을 은행과 비교하면,
고객이 장부를 직접 기록하는 방식,
즉 event가 발생했을 때, 고객이 직접 state 값을 바꾸는 방식이다.
코드를 살펴보면, 원래 count가 0이고 count 값을 바꾸고 싶을 때, setCount()를 사용한다.
고객이 count 값을 바꾸고 싶을 때마다, 직접 값을 바꿔준다.
고객이 1억명이고 장부의 state들이 아주 많고 복잡하면... 이때 고객이 직접 state를 바꾸기보다 action(주문)을 취하는 것이 낫다!
const [state, dispatch] = useReducer(reducer, initialArg, init?)
function down() {
dispatch('DOWN');
}
function reset() {
dispatch('RESET');
}
function up() {
dispatch('UP');
}
export default function App() {
function countReducer(oldCount, action) {
if (action === 'UP') {
return oldCount + 1;
} else if (action === 'DOWN') {
return oldCount - 1;
} else if (action === 'RESET') {
return 0;
}
}
const [count, countDispatch] = useReducer(countReducer, 0); // 1: reducer 함수, 2: 초기값
function down() {
countDispatch('DOWN');
}
function reset() {
countDispatch('RESET');
}
function up() {
countDispatch('UP');
}
return (
<div>
<input type="button" value="-" onClick={down} />
<input type="button" value="0" onClick={reset} />
<input type="button" value="+" onClick={up} />
<span>{count}</span>
</div>
);
}
하나를 더 추가해서 구현해보자~
number 값은 useState를 이용할 것
이때, reducer()가 number를 직접 사용하면 좋지 않다.
→ reducer()의 경우, input과 output 값만으로 함수의 동작이 달라져야지 이 함수가 직접 number에 접근하면 좋지 않다.
(= setNumber로 값을 사용하는건 좋지 않다는 뜻!)
따라서 action을 줄 때, number 값을 전달하면 좋다.
export default function App() {
const [count, countDispatch] = useReducer(countReducer, 0);
const [number, setNumber] = useState(1);
function countReducer(oldCount, action) {
if (action.type === 'UP') {
return oldCount + action.number;
} else if (action.type === 'DOWN') {
return oldCount - action.number;
} else if (action.type === 'RESET') {
return 0;
}
}
function down() {
countDispatch({ type: 'DOWN', number: number });
}
function reset() {
countDispatch({ type: 'RESET', number: number });
}
function up() {
countDispatch({ type: 'UP', number: number });
}
function changeNumber(event) {
setNumber(Number(event.target.value));
}
return (
<div>
<input type="button" value="-" onClick={down} />
<input type="button" value="0" onClick={reset} />
<input type="button" value="+" onClick={up} />
<input type="text" value={number} onChange={changeNumber} />
<span>{count}</span>
</div>
);
}