如何使用useReducer React hooks

51 阅读2分钟

看看useReducer这个React钩子有什么用处,以及如何使用它

自从React引入钩子后,我在几个项目中使用它们,它们实在是太好了。

移除所有基于类的组件使代码感觉更 "真实 "的JavaScript。而且功能组件终于可以管理状态了。

如果你是新手,先看看我的React钩子介绍吧。

我有时使用的一个钩子是useReducer

import React, { useReducer } from 'react'

这个钩子是用来管理状态的。有点像useState ,只是更复杂。

这是useStateuseReducer 的关键区别:在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钩子

现在,想象一下这个状态可以是一个有很多很多属性的对象,而不同的动作一次只能改变一个属性。这就是这个钩子的一个伟大的用例。