Counter with useReducer+Flux 的な何か
後で振り返るように。
action&state
interface Action<ActionType> { type: ActionType; payload?: any; } enum CounterActionType { Increase, Decrease } interface CounterState { count: number; } type CounterAction = Action<CounterActionType>;
function reducer(state: CounterState, action: CounterAction): CounterState { switch (action.type) { case CounterActionType.Increase: return { count: state.count + 1 }; case CounterActionType.Decrease: return { count: state.count - 1 }; } } class ActionCreater { private readonly dispach: React.Dispatch<CounterAction>; constructor(dispach: React.Dispatch<CounterAction>) { this.dispach = dispach; } increase() { const action: CounterAction = { type: CounterActionType.Increase }; this.dispach(action); } decrease() { const action: CounterAction = { type: CounterActionType.Decrease }; this.dispach(action); } }
View
interface CounterViewProps { count: number; increase: () => void; decrease: () => void; } const CounterView: React.FC<CounterViewProps> = props => ( <div> <p>Count: {props.count} </p> <button onClick={() => props.decrease()}>-</button> <button onClick={() => props.increase()}>+</button> </div> );
import React, { useReducer } from 'react'; function CounterPage(): any { const initialState: CounterState = { count: 0 }; const [state, dispach] = useReducer(reducer, initialState); const actionCreater = new ActionCreater(dispach); return ( <CounterView count={state.count} increase={() => actionCreater.increase()} decrease={() => actionCreater.decrease()} /> ); } export default CounterPage;