useReducer用最简单的话来说,就是允许我们在函数组件里面像使用redux一样通过reducer和action来管理我们组件状态的变换。

我们可以通过useContext配合实现一个函数组件中的redux。

useReducer的标准写法:

const [state, dispatch]=useReducer(reducer, initialArg, init?)

参数解析:

state  通过解构得到当前组件的状态;

dispatch  是用来触发某些改变state的action而不是直接设置state的值,至于不同的action如何产生新的state的值则在reducer里面定义;

reducer  是一个函数,形式为(oldstate,action)=>newstate,两个形参一个接收当前的state、一个接收当前dispatch的action为参数;

initialArg  如果调用者没有提供第三个init参数,这个参数代表的是这个reducer的初始状态,如果init参数有被指定的话,initialArg会被作为参数传进init函数来生成初始状态;

init(可选)这是一个用来生成初始状态的函数,initialArg  作为参数传入,函数的返回值作为初始状态。

写一个例子演示一下使用

import React,{useReducer} from 'react'export default function App() {//定义reducer函数let reducer=(initSate,action)=>{if(action.type=="MSG"){initSate.msg=action.value //把当前状态的msg修改为ation接收到的对象的msg}initSate=JSON.parse(JSON.stringify(initSate))//对象深拷贝,形成一个新的对象return initSate//返回新的状态对象,作为组件的状态}//使用useReducer,定义初始状态为{msg:"hello"}let [state,dispatch]=useReducer(reducer,{msg:"hello"})return (<div>//使用数据与useState创建的状态用法相同<p>{state.msg}</p>//调用dispatch修改状态,render的action会接收传入的对象<button onClick={()=>{dispatch({type:"MSG",value:"修改了msg数据"})}}修改仓库msg</button></div>)
}

useReducer和useState

两者的用法有点相似,都是使用hook初始化状态,然后得到的值通过解构得到当前状态和修改状态的方法。

区别:

useReducer将状态和状态的变化统一管理在reducer函数里面,这样对于一些复杂的状态管理会十分方便我们debug,因为它对状态的改变是封闭的。而由于useState返回的setState可以直接在任意地方设置我们状态的值,当我们组件的状态转换逻辑十分复杂时,它将很难debug,因为它是开放的状态管理。

难度进阶——通过useReducer、useContext、context实现一个Redux插件的功能

1、首先创建一个上下文对象

import React from 'react'
let ctx=React.createContext(null)
export default ctx;

2、将上下文引入我们的仓库组件,设置初始状态和设计reducer的处理逻辑,然后提供状态和dispatch修改函数供全局使用。

import React,{useReducer} from 'react'
import ctx from "./store"
export default function Myredux(props) {let reducer=(state,action)=>{if(action.type=="MSG"){state.msg=action.value}if(action.type=="TOKEN"){state.token=action.value}state=JSON.parse(JSON.stringify(state))return state}let [store,dispatch]= useReducer(reducer,{msg:"hello",token:"af123123"},function(arg){//可以处理数据 然后返回值作为仓库的初始状态arg.msg="123"return arg})return (<ctx.Provider value={[store,dispatch]}>{props.children}</ctx.Provider>)
}

3、最后一步,此时我们提供的数据还不能被其它组件使用,我们需要将我们的仓库组件作为根组件,这样所有组件才能访问到达到全局使用。

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from "./App.jsx"
import Myredux  from './store/index';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Myredux><App></App></Myredux>);

在其它组件中使用时,我们只需引入上下文,然后通过useContext获取提供的数据即可

import React,{useContext} from 'react'
import ctx from "./store/store"
import Box from './Box.jsx'
export default function App() {let [store,dispatch]=useContext(ctx)return (<div><h1>App</h1><p>App--{store.msg}</p><button onClick={()=>{dispatch({type:'MSG',value:"666app修改了仓库"})}}>change</button></div>)
}

到此重要的hook就差不多学完了。

hook之useRoducer相关推荐

  1. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  2. 在React Hook里使用history.push跳转

    在React Hook里使用history.push跳转 react hook里用不了this.props.history的解决方法 首先引入 import { useHistory } from ' ...

  3. 在react hook里使用mobx(配置mobx依赖)

    在powershell里安装依赖 (直接npm i mobx或者npm i mobx-react是会报错的) npm i mobx mobx-react --save save是下载到"de ...

  4. HDU-1698-Just a Hook

    HDU-1698-Just a Hook http://acm.hdu.edu.cn/showproblem.php?pid=1698 还是成段更新线段树 #include<stdio.h> ...

  5. 一套使用注入和Hook技术托管入口函数的方案

    工作中,我们可能会经常使用开源项目解决一些领域中的问题.这种"拿来主义"是一种"专业人干专业事"的思想,非常实用.(转载请指明出于breaksoftware的c ...

  6. Linux下HOOK动态链接库中API的方法

    2012年,我写了一篇介绍Windows系统下Ring3层API的hook方案--<一种注册表沙箱的思路.实现--Hook Nt函数>,其在底层使用了微软的Detours库.5年后,我又遇 ...

  7. 一种注册表沙箱的思路、实现——Hook Nt函数

    Nt函数是在Ring3层最底层的函数了,选择此类函数进行Hook,是为了提高绕过门槛.我的Hook方案使用的是微软的Detours.(转载请指明出处) Detours的Hook和反Hook的写入如下: ...

  8. Linux下C++中可使用的3种Hook方法

    Hook即钩子,截获API调用的技术,是将执行流程重定向到你自己的代码,类似于hack.如使程序运行时调用你自己实现的malloc函数代替调用系统库中的malloc函数.这里介绍下Linux下C++中 ...

  9. React useState,useEffect ,Hook是什么?什么是副作用?

    初步接触 React 中的同学可能会对 useState,useEffect ,Hook,副作用 这些命名比较陌生,一起来了解一下. Hook是什么? Hook 是钩子,我理解他是一个概念,在不使用c ...

最新文章

  1. 华为上机考试题系列(一):牛客网的奇葩操作
  2. 如何迁移#SNMP到.NET Core平台的一些体会
  3. python 搜寻蓝牙_3 Python Web搜寻器和搜寻器
  4. git 代码回滚_git代码版本管理(1)——git版本回滚
  5. 蒸妙集团用科学熏蒸法,弥补现代人在运动上的缺乏
  6. 以下不属于计算机综合处理多媒体信息的有,国家开放大学《多媒体应用技术基础》第一-二次形成性考核任务试题...
  7. vue2.0项目的环境配置以及有哪些的坑
  8. Centos7设置SSH安全策略–指定IP登陆
  9. 智慧校园APP开发的简要功能
  10. error: RPC failed; curl 56 GnuTLS recv error (-9): A TLS packet with unexpected length was
  11. 对C++一脸懵逼却又无比热爱的第一篇
  12. 量化选股宝三步走,京豆礼包你拿走
  13. springboot使用rocketmq-spring-boot-starter整合RocketMQ
  14. 汉堡包菜单_神圣的汉堡包!
  15. 关于逻辑回归中的Enter以及stepwise的区别
  16. 氨基苯酚/多巴胺仿生修饰碳纳米管/α-氧化铝/ CNTs-Ag纳米复合材料
  17. 根据在同一时间使用计算机用户的多少,2016年职称计算机WindowsXP考前冲刺试题1...
  18. 如何制作全息视频--3D max+AE搞定
  19. JAVA毕业设计进出货管理系统计算机源码+lw文档+系统+调试部署+数据库
  20. 论文格式修改技巧-公式与字不在同一行

热门文章

  1. 研究方向三选一选择FPGA/计算机视觉/故障检测
  2. 对接医疗资源,创建高质量医疗数据库,这家公司能降低跨境医疗费用吗?
  3. 淘宝电商:淘宝卖家如何快速提升店铺自然搜索流量?
  4. 被深信服上网行为管理器AC拒绝的操作如何正常访问
  5. 计算机是中北大学双一流建设学科不,中北大学创建“双一流”大学迎来新消息,网友:山西大学仍需努力...
  6. 微信点赞功能测试用例
  7. 深度学习几个基础知识
  8. iphone配置Charles抓包
  9. 驱动力来自哪里——献给迷茫的程序员
  10. MATLAB轻松绘制地图路线——已知及未知坐标下的处理方法(1)