useReducer 可看做升级版的 useState ,其强大之处在于,可以自定义复杂的响应式变量修改逻辑。
useReducer 语法
useReducer 是 hook 函数
- 第一个参数(必要): 自定义的 reducer 函数(详见下文介绍)
- 第二个参数(必要): 响应式变量的初始值
- 第三个参数(可选):自定义的 init 函数(详见下文介绍),实现惰性初始化
- 返回:一个数组,第一项为响应式变量,第二项为 dispatch 方法(详见下文介绍)
范例 – 计数器
import { useReducer } from "react"; function init(initialCount) { return { count: initialCount }; } function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; case "reset": return init(action.payload); default: throw new Error(); } } function Counter({ initialCount }) { const [state, dispatch] = useReducer(reducer, initialCount, init); return ( <> Count: {state.count} <button onClick={() => dispatch({ type: "reset", payload: initialCount })} > Reset </button> <button onClick={() => dispatch({ type: "decrement" })}>-</button> <button onClick={() => dispatch({ type: "increment" })}>+</button> </> ); } export default Counter;
父组件
import Counter from "./test.jsx"; export default function Index() { return ( <div> <Counter initialCount={0} /> </div> ); }
范例解析
若用 useState 实现,代码如下:
function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> Count: {count} <button onClick={() => setCount(initialCount)}>Reset</button> <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button> <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button> </> ); }
对比可知:
- useReducer 将响应式变量作为 state 对象的属性来处理
- setCount 的参数为响应式变量的新值
- dispatch 的参数为修改响应式变量的逻辑参数,统一在 reducer 中定义具体的处理逻辑
init 函数
用于对响应式变量进行惰性初始化,传入初始值参数,返回响应式变量的初始值。
function init(initialCount) { return { count: initialCount }; }
reducer 函数
描述复杂的响应式变量修改逻辑
- 第1个参数为:响应式变量
- 第2个参数为:dispatch 方法传入的参数(内含修改逻辑的关键信息)
- 返回 state 的新值
function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; case "reset": return init(action.payload); default: throw new Error(); } }
dispatch 方法
用于触发响应式变量的改变
- 参数为一个对象,内含修改响应式变量的逻辑参数
- dispatch 方法的执行,实际上是执行 reducer 函数,实现 state 的更新,并触发视图更新。