TypeScriptでredux向けのreducerやaction生成関数を作る時、typesafe-actionsを使っているのですが、
reduxを使わない類似のフックAPIであるReact.useReducerを使うときもtypesafe-actionsが提供する型や定義の恩恵が欲しいと思い、やったら上手く行ったのでサンプルコードの形で置いておきます。
interface State {
counter: number;
}
export const increment = createAction("INCREMENT", resolve => {
return (delta:number) => resolve(delta);
});
export const decrement = createAction("DECREMENT", resolve => {
return (delta:number) => resolve(delta);
});
type Action = ReturnType<typeof increment> | ReturnType<typeof decrement>;
// ここのinitialStateである `{}` は実際の挙動に影響しないようです。
const baseReducer = createReducer<State, Action>({})
.handleAction(
[increment],
(state, action: ReturnType<typeof increment>): State => ({
counter: state.counter + action.payload
})
)
.handleAction(
[decrement],
(state, action: ReturnType<typeof decrement>): State => ({
counter: state.counter - action.payload
})
)
type Reducer = React.Reducer<State, Action>;
// React.useReducerで使える形式にadoptしたReducer
const reducer: Reducer = (state, action) => {
// typesafe-actions と React.Reducer では若干違う部分があるので橋渡し
return baseReducer.handlers[action.type](state, action);
}
const initialState: State = {
counter: 0
};
const component = ()=> {
const [state, dispatch] = useReducer(reducer, initialState);
return (
);
}