看看useReducer这个React钩子有什么用处,以及如何使用它
自从React引入钩子后,我在几个项目中使用它们,它们实在是太好了。
移除所有基于类的组件使代码感觉更 "真实 "的JavaScript。而且功能组件终于可以管理状态了。
如果你是新手,先看看我的React钩子介绍吧。
我有时使用的一个钩子是useReducer 。
import React, { useReducer } from 'react'
这个钩子是用来管理状态的。有点像useState ,只是更复杂。
这是useState 和useReducer 的关键区别:在useReducer ,状态是通过传递消息而不是调用更新函数来改变的。
如果你知道Redux的工作原理,这基本上是一样的。一个reducer是一个纯函数,它根据之前的状态和已经派发的动作来计算下一个状态。
(currentState, action) => newState
"纯函数 "是什么意思?一个纯函数接受一个输入并返回一个输出,而不改变输入或其他任何东西。这意味着,一个reducer会返回一个全新的状态来替代之前的状态。
一个还原器应该
- 不改变其参数
- 不产生副作用(不改变任何API调用)。
- 不调用非纯函数,即根据输入以外的因素改变其输出的函数(例如:
Date.now()或Math.random())。
没有强化措施,但你应该坚持遵守规则。这有一个很好的好处:还原器的测试要简单得多,因为它们没有副作用。
这允许集中管理状态,允许组件通过发送消息来修改状态,也允许你在组件中使用(和改变)更复杂的状态。
让我们举个例子,用一个计数器组件。
useReducer 它接受一个还原器函数和一个初始状态值作为参数。在这个例子中,我们的状态是一个整数,从0开始。
const Counter = () => {
const [state, dispatch] = useReducer(reducer, 0)
}
减速器是一个函数,如上所述,它接受当前状态和一个动作,可以是你想要的任何类型的值。在这个例子中,它是一个字符串。
const reducer = (state, action) => {
switch (action) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
throw new Error()
}
}
我们还让该组件输出一些JSX,以使这个简单的应用程序发挥作用。
const Counter = () => {
const [count, dispatch] = useReducer(reducer, 0)
return (
<>
Counter: {count}
<button onClick={() => dispatch('INCREMENT')}>+</button>
<button onClick={() => dispatch('DECREMENT')}>-</button>
</>
)
}
这里是Codepen上的完整例子。
在CodePen上看到Flavio Copes (@flaviocopes)的PenReact useReducer钩子。
现在,想象一下这个状态可以是一个有很多很多属性的对象,而不同的动作一次只能改变一个属性。这就是这个钩子的一个伟大的用例。