跳到主要内容

💪🏻useReducer

useReduceruseState 的替代方案,它接收一个形如 (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 };