React hooks - useReducer

2024-05-23 21:12

本文主要是介绍React hooks - useReducer,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

useReducer

        • 用法
          • 使用
          • 使用 Immer 更简单的编写 reducer
        • 注意事项

用法
  1. 可同时更新多个状态,且能把对状态的修改从组件中独立出来,状态更新逻辑较复杂时可以考虑使用。
  2. 代码逻辑更清晰,代码行为易预测:组件负责发出行为,useReducer 负责更新状态
const [state, dispatch] = useReducer(reducer, initState, initAction?)
  1. reducer=(prevState, action)=> { return ‘处理好的新状态’ } 状态处理函数,接收上一次的旧值,以及dispatch穿入的信息对象,进行一系列处理,返回处理好的新状态(一定要是个崭新的对象,为了组件能够监听到状态的变化)
  2. initState 初始状态
  3. initAction 预处理函数,可选,将初始状态传入进行预处理,返回值被当做初始状态
  4. state 获取状态值
  5. dispatch({type: ‘此次操作的类型’, payload: ‘提交此次操作需要用到的数据’ }) 修改状态值,接收一个信息对象,触发reducer函数的执行,更新 state状态,状态更新导致组件重新渲染
使用
import React from 'react'// 定义默认值的类型,从默认值身上获取
type UserType = typeof defaultState
// 初始数据
const defaultState = { name: 'liulongbin', age: 16 }
// 状态处理函数
const reducer = (prevState: UserType) => {console.log('触发了 reducer 函数')return prevState
}
// 预处理函数
const initAction = (initAction: UserType) => {return {...initAction , age:Math.round(Manth.abs(initState.age))||18}
}

父组件

export const Father: React.FC = () => {const [state, dispatch] = useReducer(reducer, defaultState,initAction)return (<div><button>修改 name 的值</button><div className="father"><Son1 /><Son2 /></div></div>)
}

子组件1

const Son1: React.FC<UserType & {dispatch : React.Dispatch<ActionType>}> = (props) => {const {dispatch, ...user} = propsconst changeAge = () => {dispatch({type: 'AGE_INCREMENT', payload: 2}) // 年龄一次自增2}return (<div className="son1">{JSON.stringify(user)}<button onClick={()=>changeAge}>年龄自增2</button></div>)
}

子组件2

const Son2: React.FC<UserType & {dispatch : React.Dispatch<ActionType>}> = (props) => {const {dispatch, ...user} = propsconst changeAge = () => {dispatch({type: 'AGE_DECREMENT', payload: 1}) // 年龄一次自减1}return (<div className="son2">{JSON.stringify(user)}<button onClick={()=>changeAge}>年龄自减1</button>{/* 传第二手dispatch */}<GrandSon dispatch={ dispatch } /> </div>)
}

孙子组件

const GrandSon: React.FC<{dispatch : React.Dispatch<ActionType>}> = (props) => {const { dispatch } = propsconst reset = () => {dispatch({type: 'RESET'}) }return (<div className="grand-son"><button onClick={()=>reset}>重置</button></div>)
}

样式

.father {display: flex;justify-content: space-between;width: 100vw;
}.son1 {background-color: orange;min-height: 300px;flex: 1;padding: 10px;
}.son2 {background-color: lightblue;min-height: 300px;flex: 1;padding: 10px;
}
使用 Immer 更简单的编写 reducer

从 use-immer 中导入 useImmerReducer 函数,并替换掉 React 官方的 useReducer 函数的调用

npm install immer use-immer -S

修改 reducer 函数中的业务逻辑,case 代码块中不需要 return 新对象了,可在 prevState 上进行修改
因为 Immer 内部会复制并返回新对象

// 状态处理函数
const reducer = (prevState: UserType, action: ActionType) => {console.log('触发了 reducer 函数', action)switch (action.type) {// 修改名字case 'UPDATE_NAME':prevState.name = action.payloadbreak// 年龄自增payloadcase 'INCREMENT':prevState.age += action.payloadbreak// 年龄自减payloadcase 'DECREMENT':prevState.age -= action.payloadbreak// 重置case 'RESET':return initAction(defaultState)default:return prevState} 
}
export const Father: React.FC = () => {// 把 useReducer() 的调用替换成 useImmerReducer()const [state, dispatch] = useImmerReducer(reducer, defaultState,initAction)
}
注意事项
  1. 状态被useReducer接管后,不能直接修改 state 的值,因为存储在 useReducer 中的数据都是“不可变”的,要想修改 useReducer 中的数据,必须使用 dispatch 函数 触发 reducer 函数的重新计算。

这篇关于React hooks - useReducer的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/996432

相关文章

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

css中的 vertical-align与line-height作用详解

《css中的vertical-align与line-height作用详解》:本文主要介绍了CSS中的`vertical-align`和`line-height`属性,包括它们的作用、适用元素、属性值、常见使用场景、常见问题及解决方案,详细内容请阅读本文,希望能对你有所帮助... 目录vertical-ali

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

CSS @media print 使用详解

《CSS@mediaprint使用详解》:本文主要介绍了CSS中的打印媒体查询@mediaprint包括基本语法、常见使用场景和代码示例,如隐藏非必要元素、调整字体和颜色、处理链接的URL显示、分页控制、调整边距和背景等,还提供了测试方法和关键注意事项,并分享了进阶技巧,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分