Re: 新手让网页 act 起来: Day19 - React Hooks 之 useReducer

前言

如果有接触过 Redux 的话,应该会对这个 hook 有亲切感。如果是像我一样没有接触的话也没关系,其实可以把 useReducer 想像成另一种 useState,从这个角度去学习会比较好理解,那今天就让我来了解一下怎麽使用 useReducer 吧!

useReducer

useReducer 可以接收三个参数:

  1. 一个 callback
  2. 初始值
  3. lazy initialize callback

并且回传一个两个值的阵列,第一个值跟 useState 一样,就是会拿到 initialValue,而第二个值是一个函式,可以把先把它想像成是另一种的 setState,所以写起来会是长这个样子:

const [state, setState] = useReducer(()=>{}, initialValue, ()=>{})

那第一个 callback 到底要写些什麽呢?惯例上会称它叫 reducer,那它会接收两个参数,第一个是当下的 state ,第二个值会是当我们使用 useReducer 回传的 setState ,呼叫时传进去的参数。例如说:

const [state, setState] = useReducer((state, newState)=>{
console.log(newState) // 印出 3 
}, initialValue)

setState(3)

接下来就让我们实际使用 useReducer 来完成 Counter!

使用 useReducer 改写 Counter

先来看看之前的 useState 范例

const Counter = () => {
  const [count, setCount] = React.useState(0)
  
  const increaseHandler = () => {
    setCount(count + 1)
  
  }

  const decreaseHandler = () => {
    if (count === 0) return

    setCount(count - 1)
  }

  return (
    <div className="container">
      <button className="minus" onClick={decreaseHandler}>-</button>
      <span className="number">{count}</span>
      <button className="plus" onClick={increaseHandler}>+</button>
    </div>
  )
};

ReactDOM.render(<Counter />, document.getElementById('root'))

将 useState 换成 useReducer ,并建立 countReducer

function countReducer(state, newState){

}

const [count, setCount] = React.useReducer(countReducer, 0)

接下来只要在 countReducer 回传新的 state ,就会更新 count 的数值并触发 re-render。

function countReducer(state, newState){
  return newState
}

计数器就顺利的改写完了,会发现说 useReducer 其实就跟 useState 差不多,只是多了一个 reducer callback 而已。

但实际是上,比较常见的做法会把 useReducer 回传的 setState 称作 dispatch ,而 reducer 的第二个参数为 action。

再来改写一下 Counter 吧!

function countReducer(state, action){
  switch (action.type) {
    case 'increment': 
      return state + 1;
    case 'decrement': 
      return state - 1;
    default: 
      throw new Error(`no ${action.type} type in counterReducer`)
  }
}

const [count, dispatch] = React.useReducer(countReducer, 0)

const increaseHandler = () => {
  dispatch({type: 'increment'})

}

const decreaseHandler = () => {  
  if (count === 0) return

  dispatch({type: 'decrement'})
}

顺利的话,Counter 的功能就会如图正常的运作

以上就是关於 useReducer 的基本使用方式,但从上面的例子会发现,这样写起来比 useState 麻烦多了,为什麽要用 useReducer 呢?这个部分就让我们之後来介绍吧!关於今天的内容有什麽问题都欢迎在下方留言~~

该文章同步发布於:我的部落格


<<:  不玩惹把钱还给我好否 - 抽单

>>:  EP22 - 持续部署使用 Octopus Deploy 二部曲,安装 Octopus Deploy

【Day 17】for 回圈的范例讲解

今天,我们先来看看阶乘要怎麽写~ 我的程序码长这样: #include<stdio.h>...

【Day 29】- 应对反爬虫技术-综合篇

前情提要 昨天跟各位读者简介了反爬虫技术中,较常出现的验证码之应对方法。 开始之前 今天要跟各位介绍...

D19/ 要权限的时後有 Launcher has not been initialized,怎麽办? - SideEffect

今天大概会聊到的范围 SideEffect DisposableEffect 今天要讲的东西是 S...

DAY12-EXCEL统计分析:卡方检定实例

卡方检定 今天来实作单一常态母体变异数检定的题目。 假如一家面包店希望生产的蛋黄酥重量的变异数维持在...

【这些年我似是非懂的 Javascript】Day 28 - 物件 # Part 4 # 特性描述器 Combo

昨天分享了特性组合的一般单独的使用方法, 今天要来分享一下他们的 Combo 连技和相关用到的东西...