React Hooks 之 useReducer useRef useContext和useMemo 的用法

Stella981
• 阅读 524

之前文章中我们有讲到的 useState hook 和 useEffect hook 的一些概念和基本用法,趁着周末空闲时间,我们一起来看看 React 为我们提供的其他 hooks 的一些基本使用吧。

useReducer

useReducer hook 接收两个参数,第一个是参数是一个函数(这是一个 reducer函数:它接收两个参数 state 和 action,它会根据 action 类型返回一个新的state),第二个参数是一个初始状态(intialState)。语法如下:

   1.  `const [newState, dispatch] = useReducer((state, action) => {`

   
     
   
   
   2.   `//根据派发出去的 action 类型,返回一个 newState`

   
     
   
   
   3.  `}, intialState)`

  
    
  
  
  

看一个例子:

   1.  `const Counter = () => {`

   
     
   
   
   2.   `//count对应 reducer 返回的nweState`

   
     
   
   
   3.   `//dipatch 负责派发一个 action(动作)`

   
     
   
   
   4.   `//action是一个具有 type 属性的一个javascript对象`

   
     
   
   
   5.   `const [count, dispatch] = useReducer((state, action) => {`

   
     
   
   
   6.   `switch (action.type) {`

   
     
   
   
   7.   `case 'add':`

   
     
   
   
   8.   `return state + 1;`

   
     
   
   
   9.   `case 'sub':`

   
     
   
   
   10.   `return state - 1;`

   
     
   
   
   11.   `default:`

   
     
   
   
   12.   `return state;`

   
     
   
   
   13.   `}`

   
     
   
   
   14.   `}, 0)`

   
     
   
   
   15.   `return (`

   
     
   
   
   16.   `<div>`

   
     
   
   
   17.   `<div>CountSum: {count}</div>`

   
     
   
   
   18.   `<button onClick={() => dispatch({ type: 'add' })}>Add</button>`

   
     
   
   
   19.   `<button onClick={() => dispatch({ type: 'sub' })}>Substract</button>`

   
     
   
   
   20.   `</div>`

   
     
   
   
   21.   `)`

   
     
   
   
   22.  `}`

   
     
   
   
   23.    

   
     
   
   
   24.  `export default Counter;`

  
    
  
  
  

useReducer hook 的流程可以总结为:

事件发生 -->调度方法(dispatch)派发一个动作(action) --> reducer 根据派发的动作类型(action.type)返回一个新的状态(newState)

useRef hook

Refs 用于访问在 render 呈现的 DOM 或 React 元素。在以前的 React 版本中使用refs的标准方法是这样的:

   1.  `//16.3提供`

   
     
   
   
   2.  `class RefHook extends React.Component {`

   
     
   
   
   3.   `constructor(props) {`

   
     
   
   
   4.   `super(props);`

   
     
   
   
   5.   `//创建ref`

   
     
   
   
   6.   `this.myRef = React.createRef();`

   
     
   
   
   7.   `}`

   
     
   
   
   8.    

   
     
   
   
   9.   `render() {`

   
     
   
   
   10.   `return <div ref={this.myRef}></div>`

   
     
   
   
   11.   `}`

   
     
   
   
   12.  `}`

   
     
   
   
   13.  `export default RefHook;`

  
    
  
  
  

现在可以使用 useRef hook:

   1.  `//16.8提供`

   
     
   
   
   2.  `function RefHook() {`

   
     
   
   
   3.    

   
     
   
   
   4.   `const myRef = useRef();`

   
     
   
   
   5.   `function handleChange() {`

   
     
   
   
   6.   `console.log(myRef);`

   
     
   
   
   7.   `}`

   
     
   
   
   8.    

   
     
   
   
   9.   `return <div onChange={handleChange} ref={myRef}></div>`

   
     
   
   
   10.  `}`

   
     
   
   
   11.    

   
     
   
   
   12.  `export default RefHook;`

  
    
  
  
  

useContext hook

Context API 解决了 React 最大的问题之一就是 props 多层组件传递。在以前的版本中:

   1.  `const ThemeContext = React.createContext();`

   
     
   
   
   2.  `function ContextComponent() {`

   
     
   
   
   3.   `return (`

   
     
   
   
   4.   `<ThemeContext.Provider value="dark">`

   
     
   
   
   5.   `<ThemeButton />`

   
     
   
   
   6.   `</ThemeContext.Provider>`

   
     
   
   
   7.   `)`

   
     
   
   
   8.  `}`

   
     
   
   
   9.    

   
     
   
   
   10.  `function ThemeButton() {`

   
     
   
   
   11.   `return (`

   
     
   
   
   12.   `<ThemeContext.Consumer>`

   
     
   
   
   13.   `{(theme) => <div> This is theme: {theme} </div>}`

   
     
   
   
   14.   `</ThemeContext.Consumer>`

   
     
   
   
   15.   `)`

   
     
   
   
   16.  `}`

   
     
   
   
   17.    

   
     
   
   
   18.  `export default ContextComponent;`

  
    
  
  
  

useContext hook 提供了使用上下文的很多优化的方式。

   1.  `import React, { useContext } from 'react';`

   
     
   
   
   2.    

   
     
   
   
   3.  `const ThemeContext = React.createContext();`

   
     
   
   
   4.  `function ContextComponent() {`

   
     
   
   
   5.   `return (`

   
     
   
   
   6.   `<ThemeContext.Provider value="dark">`

   
     
   
   
   7.   `<Theme />`

   
     
   
   
   8.   `</ThemeContext.Provider>`

   
     
   
   
   9.   `)`

   
     
   
   
   10.  `}`

   
     
   
   
   11.    

   
     
   
   
   12.  `function Theme() {`

   
     
   
   
   13.   `const theme = useContext(ThemeContext);`

   
     
   
   
   14.   `return (`

   
     
   
   
   15.   `<div> This is theme: {theme} </div>`

   
     
   
   
   16.   `)`

   
     
   
   
   17.  `}`

   
     
   
   
   18.    

   
     
   
   
   19.  `export default ContextComponent;`

  
    
  
  
  

useMemo hook

React有一个名为 useMemo 的钩子,它让我们记忆复杂而昂贵的函数,这样我们就可以避免每次重复的渲染。

它是采用了 Memoization 思想  它是 JavaScript 中的一种技术,通过缓存结果并在下一个操作中重新使用缓存来加速查找费时的操作。

比方说,我们必须编写一个函数来查找给定数字的平方。

   1.  `const calc = num => {`

   
     
   
   
   2.   `return num * num;`

   
     
   
   
   3.  `}`

   
     
   
   
   4.  `calc(4); // 16`

   
     
   
   
   5.  `calc(5); // 25`

   
     
   
   
   6.  `calc(35); // 1225`

   
     
   
   
   7.  `calc(35); // 1225`

   
     
   
   
   8.  `calc(5); // 25`

   
     
   
   
   9.  `calc(35); // 36`

  
    
  
  
  

我们计算了两次 35 的平方,这还好因为它不是什么密集的操作,如果是非常耗时的操作,就会变得很昂。采用  Memoization  可以这么做:

   1.  `const cache = {};`

   
     
   
   
   2.  `const calc = num => {`

   
     
   
   
   3.   `let result = cache[num];`

   
     
   
   
   4.   `if(!result) {`

   
     
   
   
   5.   `result = num * num;`

   
     
   
   
   6.   `cache[num] = result;`

   
     
   
   
   7.   `}`

   
     
   
   
   8.   `return result;`

   
     
   
   
   9.  `}`

   
     
   
   
   10.  `calc(4);`

   
     
   
   
   11.  `calc(5);`

   
     
   
   
   12.  `calc(35); //1225`

   
     
   
   
   13.  `calc(35); //1225`

   
     
   
   
   14.  `console.log(cache); // {4: 16, 5: 25, 35: 1225}` 

  
    
  
  
  

从上边的例子中我们可以看到,当我们再计算 35 的平方时,不需要重新计算,而直接从缓存中选择值即可,提高了程序的性能。

在 React 中,有些时候我们不想每次都重新渲染组件,基于 Memoization 思想 useMemo hook 就是负责记忆相应的组件,只有在数据发生变化时组件才会重新渲染。

   1.  `function Parent({ a, b }) {`

   
     
   
   
   2.   `// 当 a b 有一个发生变化时 才重新渲染`

   
     
   
   
   3.   `const child1 = useMemo(() => <Child1 a={a} b={b}/>, [a, b]);`

   
     
   
   
   4.   `// 当 b 发生变化时 才重新渲染`

   
     
   
   
   5.   `const child2 = useMemo(() => <Child2 b={b} />, [a, b]);`

   
     
   
   
   6.   `return (`

   
     
   
   
   7.   `<>`

   
     
   
   
   8.   `{ child1 }`

   
     
   
   
   9.   `{ child2 }`

   
     
   
   
   10.   `</>`

   
     
   
   
   11.   `)`

   
     
   
   
   12.  `}`

  
    
  
  
  

如果公众号里的文章对您有所帮助,麻烦大家点击关注并帮助分享下,在这里谢谢大家啦。

React Hooks 之 useReducer useRef useContext和useMemo 的用法

****一扫

React Hooks 之 useReducer useRef useContext和useMemo 的用法

****_注我
_

React Hooks 之 useReducer useRef useContext和useMemo 的用法

React Hooks 之 useReducer useRef useContext和useMemo 的用法

本文分享自微信公众号 - 像素摇摆(pxDance)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
React系列
React系列Mixin、HOC、RenderProps(上)React系列轻松学会Hooks(中)React系列自定义Hooks很简单(下)我们在第二篇文章中介绍了一些常用的hooks,接着我们继续来介绍剩下的hooks吧useReducer作为useState的替代方案。它接收一个形如(sta
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这