React.js
React-TypeScript (UseReducer 톺아보기)
홍준혁 [Hong-JunHyeok]
2020. 11. 23. 14:45
728x90
reducer 코드를 보면서 이해해 보는 시간을 가져보도록 하자
import React, { useReducer } from "react";
type Color = "red" | "orange" | "yellow";
type State = {
count: number;
text: string;
color: Color;
isGood: boolean;
};
type Action =
| { type: "SET_COUNT"; count: number }
| { type: "SET_TEXT"; text: string }
| { type: "SET_COLOR"; color: Color }
| { type: "TOGGLE_GOOD" };
function reducer(state: State, action: Action): State {
switch (action.type) {
case "SET_COUNT":
return {
...state,
count: action.count,
};
case "SET_TEXT":
return {
...state,
text: action.text,
};
case "SET_COLOR":
return {
...state,
color: action.color,
};
case "TOGGLE_GOOD":
return {
...state,
isGood: !state.isGood,
};
default:
throw new Error("Unhandled Error");
}
}
function ReducerSample() {
const [state, dispatch] = useReducer(reducer, {
count: 0,
text: "Hello",
color: "red",
isGood: true,
});
const setCount = () =>
dispatch({
type: "SET_COUNT",
count: 5,
});
const setText = () =>
dispatch({
type: "SET_TEXT",
text: "bye",
});
const setColor = () =>
dispatch({
type: "SET_COLOR",
color: "orange",
});
const toggleGood = () => {
dispatch({
type: "TOGGLE_GOOD",
});
};
return (
<div>
<p>
<code>count: </code> {state.count}
</p>
<p>
<code>text: </code> {state.text}
</p>
<p>
<code>color: </code> {state.color}
</p>
<p>
<code>isGood: </code> {state.isGood ? "true" : "false"}
</p>
<button onClick={setCount}>SET_COUNT</button>
<button onClick={setText}>SET_TEXT</button>
<button onClick={setColor}>SET_COLOR</button>
<button onClick={toggleGood}>TOGGLE_GOOD</button>
</div>
);
}
export default ReducerSample;
간단히 작성해본 리액트 코드이다. Type들을 작성해줘서 프로그래머 입장에서 사용하기 편하게 작업해주었다.
Color 타입을 설정해 줌으로써 red , orange , yellow만 받을 수 있게 설정해 주었다.
State 타입을 설정해 줌으로써 count , text , color , isGood의 state를 관리할 수 있게 설정해 주었다.
Action 타입을 설정해 주었다. 각 액션 타입에 기능을 할 수 있게 하였다.
스위치 문을 돌리면서 각 액션 타입에 맞는 기능을 구현하였다
다음은 버튼 이벤트가 있을 때 실행할 함수들이다.
JSX부분은 이렇게 작성해 주었다
난 아직도 리듀서를 사용하는 게 헷갈린다... 하지만 리듀서는 상태 관리하는데 중요하기 때문에
익혀두는 것이 좋겠다.
728x90