💪🏻useReducer
useReducer 是 useState 的替代方案,它接收一个形如 (state, action) => newState
的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。
const [state, dispatch] = useReducer(reducer, initState);
useReducer 使用示例,拿计数器举例:
Counter/index.tsx
import { useReducer } from "../../hooks/use_reducer";
import './index.css';
interface State {
count: number
}
interface CountAction {
type: string
}
const initState: State = {count: 0}
const reducer = (state: State , action: CountAction) => {
switch (action.type) {
case "increment":
return {count: ++state.count}
case "decrement":
return {count: --state.count}
case "reset":
return {count: 0}
default:
throw new Error("action type invalid.")
}
}
export default function Counter() {
const [state, dispatch] = useReducer(reducer, initState);
return (<div className="container">
<div className="title">自定义hook useReducer</div>
Count: <span className="count">{state.count}</span>
<div className="button">
<button onClick={() => dispatch({type: "increment"})}>increment</button>
<button onClick={() => dispatch({type: "decrement"})}>decrement</button>
<button onClick={() => dispatch({type: "reset"})}>reset</button>
</div>
</div>);
}
hooks/use_reducer.ts
import { useState } from "react";
const useReducer = <S, A>(reducer: (state: S, action: A) => S, initState: S): [S, (action: A) => void] => {
const [state, setState] = useState<S>(initState);
const dispatch = (action: A) => {
setState(reducer(state, action));
};
return [state, dispatch];
};
export { useReducer };