출처 : 유튜브 별코딩 https://www.youtube.com/watch?v=tdORpiegLg0
reducer는 dispatch에 담긴 action의 내용에 따라 state를 업데이트해주는 역할을 한다.
예를 들어, A가 은행(reducer)에서 예금 거래내역(state)를 업데이트하려고 한다면, 은행에 요구(dispatch)를 하는데 그 요구의 내용(action)이 "만원을 입금해주세요."인 것이다. 즉 은행(reducer)이 철수의 요구의 내용(dispacth의 action)에 따라 거래내역(state)를 업데이트 해준다.
Dispatch함수의 인자에 Action넣어서 Reducer에게 보낸다 → Reducer가 받아서 Action내용 대로 State를 업데이트한다.
import React, { useReducer, useState } from "react";
const ACTION_TYPES = {
DEPOSIT: "deposit",
WITHDRAW: "withdraw"
};
useState의 초기값(0), 그리고 useReducer에 reducer와 초기값(0)을 넣는다. number state는 input값의 상태값이다.
function App() {
const [money, dispatch] = useReducer(reducer, 0);
const [number, setNumber] = useState(0);
버튼 클릭 시 reducer로 보낼 요구사항 (dispatch안의 action)을 넣는다.
return (
<div className="App">
<h1>잔고: {money}원</h1>
<input
type="number"
value={number}
onChange={(e) => {
setNumber(parseInt(e.target.value));
}}
step="1000"
/>
<button
onClick={() => {
dispatch({ type: ACTION_TYPES.DEPOSIT, payload: number });
}}
>
{" "}
예금{" "}
</button>
<button
onClick={() => {
dispatch({ type: ACTION_TYPES.WITHDRAW, payload: number });
}}
>
{" "}
출금{" "}
</button>
</div>
);
switch문으로 action type에 따라 실행할 내용을 구분한다.
deposit일 경우 기존 state에 payload에 담긴 값을 더하고, withdraw의 경우 기존 state에 payload에 담긴 값을 뺀다.
const reducer = (state, action) => {
switch (action.type) {
case ACTION_TYPES.DEPOSIT:
return state + action.payload;
case ACTION_TYPES.WITHDRAW:
return state - action.payload;
default:
return state;
}
};
import React, { useReducer, useState } from "react";
import "./styles.css";
const ACTION_TYPES = {
DEPOSIT: "deposit",
WITHDRAW: "withdraw"
};
const reducer = (state, action) => {
switch (action.type) {
case ACTION_TYPES.DEPOSIT:
return state + action.payload;
case ACTION_TYPES.WITHDRAW:
return state - action.payload;
default:
return state;
}
};
function App() {
const [money, dispatch] = useReducer(reducer, 0);
const [number, setNumber] = useState(0);
return (
<div className="App">
<h1>잔고: {money}원</h1>
<input
type="number"
value={number}
onChange={(e) => {
setNumber(parseInt(e.target.value));
}}
step="1000"
/>
<button
onClick={() => {
dispatch({ type: ACTION_TYPES.DEPOSIT, payload: number });
}}
>
{" "}
예금{" "}
</button>
<button
onClick={() => {
dispatch({ type: ACTION_TYPES.WITHDRAW, payload: number });
}}
>
{" "}
출금{" "}
</button>
</div>
);
}
export default App;