目录

前言:

1.react的执行机制带来的两个问题

1.1 只在 React 函数中调用 Hook;

1.2 不要在循环、条件或嵌套函数中调用 Hook;

1.3 刨析:

1.4 小结:为什么不要在循环、条件或嵌套函数中调用 Hook?

1.4 相应的源码:

2.setState到底是同步还是异步?

2.1 setState小结:

3. 逻辑复用:高阶组件(HOC)、render props、hooks

3.1 举例场景:

3.2 高阶组件的方式:

3.3 高阶组件小结:

3.4 Render props方式:

3.5 Render props方式小结:


前言:

看了一晚上react源码,有些感悟,趁着还没忘,赶紧记录下来。


1.react的执行机制带来的两个问题

之前看react文档,说是在不要再以下两种情况下使用hooks:

1.1 只在 React 函数中调用 Hook

1.2 不要在循环、条件或嵌套函数中调用 Hook

第一条好理解,因为react hooks本来就是给函数组件用的,在普通函数中使用没有意义。

第二条就令人困扰了,为啥?

先看下假设我就在条件中使用会有什么后果吧。执行以下代码后,第一次正常,控制台无报错,但是再点击一次修改姓名按钮后,就会报错

因为经过第一次渲染后,再点击进入函数的时候要执行的hook少了,和报错的提示是一样的

import React, { useState } from "react";
let isMounted = false;
function PersonalInfoComponent() {let name, age, career, setName;console.log("isMounted", isMounted);if (!isMounted) {[name, setName] = useState("接着奏乐接着舞。");[age] = useState(18);isMounted = true;}[career] = useState("前端开发");console.log("career", career);return (<div className="personalInfo"><p>姓名:{name}</p><p>年龄:{age}</p><p>职业:{career}</p><buttononClick={() => {setName("接着奏乐接着舞2。");}}>修改姓名</button></div>);
}export default PersonalInfoComponent;

1.3 刨析:

通过源码得知:Hooks在首次渲染和更新渲染(除了首次渲染之外的)时分别执行了不同的逻辑,他的执行是一个链式的表(A==》B==》C),即:首次渲染时构建这个链表,其他时候都是根据这个链表依次遍历,是有顺序的,就和数组遍历差不多的道理,那么上面的情况就明朗了,上面用了判断有时候3个hook成立有时候1个hook成立,那就很可能出错。

1.4 小结:为什么不要在循环、条件或嵌套函数中调用 Hook?

答案是:hooks的首次渲染和更新渲染执行的是不同的逻辑,第一次渲染时会构建链表,后续的渲染会根据这个链表依次遍历渲染。

因此在循环(会多会少)、条件(会多会少)、嵌套函数(有时执行有时不执行)中均不可使用(导致不可预测的问题)

1.4 相应的源码:

-----定义useState  开始------------
export function useState(initialState) {const dispatcher = resolveDispatcher();return dispatcher.useState(initialState);
}
-----定义useState  结束------------
当函数组件进入 render 阶段 的时候,
如果发现组件内存在 Hooks ,
那么会调用 renderWithHooks (opens new window)方法,
在这个方法中会根据不同渲染情况对当前的 dispatcher 进行赋值
ReactCurrentDispatcher.current =current === null || current.memoizedState === null ?HooksDispatcherOnMount :HooksDispatcherOnUpdate;
--------最终的结果--------
通过上面的代码可以看到:
第一次渲染执行的是 :HooksDispatcherOnMount函数
后面的渲染执行的是:HooksDispatcherOnUpdate函数

2.setState到底是同步还是异步?

先说结论:时而同步时而异步,结合原理具体说说?

通过研究源码可以得出:setState的执行是批量更新+开关锁

意思就是,react不会你改一次它渲染一次,而是攒着,等你改完了,我只需要修改一次就好了,我写一个伪代码包含开关锁的使用哈:

看我图上的标注后是否恍然大悟,那么上图会打印1 1这个结果也是可以接受了。

这就会使得setState是异步。

2.1 setState小结:

setState 并不是单纯同步或异步的,它的表现会因调用场景的不同而不同:

在 React 钩子函数及合成事件中,它表现为异步;

而在 setTimeout 、 setInterval 等函数中,包括在 DOM 原生事件中,它都表现为同步(原因是,这个锁是同步执行,而异步肯定比同步晚,等执行settimeout里面的时候锁已经开了)

这种差异,本质上是由 React 事务机制和批量更新机制的工作方式来决定的。


3. 逻辑复用:高阶组件(HOC)、render props、hooks

3.1 举例场景:

我要判断用户是否登录来展示不同的内容,且这个功能我要在跟多个地方使用。

3.2 高阶组件的方式:

下面的代码例子就是使用高阶组件封装的,我们只需在要用的时候,传入组件即可

import checkUserAccess from './utilsconst withCheckAccess = (WrappedComponent) => {//checkUserAccess()方法返回一个布尔值来确定是否登录,是咱们封装的逻辑 const isAccessible = checkUserAccess()  // 将 isAccessible(是否登录) 这个信息传递给目标组件const targetComponent = (props) => (<div className="wrapper-container"><WrappedComponent {...props} isAccessible={isAccessible} /></div>);return targetComponent;
};----------使用-----------
const EnhancedAComponent = withCheckAccess(Acomponent);

3.3 高阶组件小结:

高阶组件说白了,就是一个函数接收一个组件,经过函数处理返回一个加强过的组件。


3.4 Render props方式:


import checkUserAccess from './utils// 定义 render props 组件
const CheckAccess = (props) => {const isAccessible = checkUserAccess()// 将 isAccessible(是否登录) 这个信息传递给目标组件return <React.Fragment > {props.children({...props,isAccessible})} </React.Fragment>
};
-------使用如下---------
<CheckAccess>{(props) => {const { isAccessible } = props;return <ChildComponent {...props} isAccessible={isAccessible} />}}
</CheckAccess>

3.5 Render props方式小结:

Render props说白了,就是应该是一个React 组件,并且它的子组件需要以函数形式存在。。

深入理解React Hooks相关推荐

  1. 理解 React Hooks

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由志航发表于云+社区专栏 TL;DR 一句话总结 React Hooks 就是在 react 函数组件中,也可以使用类组件(classe ...

  2. 通过 React Hooks 声明式地使用 setInterval

    2019独角兽企业重金招聘Python工程师标准>>> 本文由云+社区发表 作者:Dan Abramov 接触 React Hooks 一定时间的你,也许会碰到一个神奇的问题: se ...

  3. 精读《怎么用 React Hooks 造轮子》

    1 引言 上周的 精读<React Hooks> 已经实现了对 React Hooks 的基本认知,也许你也看了 React Hooks 基本实现剖析(就是数组),但理解实现原理就可以用好 ...

  4. React Hooks 原理理解

    文章目录 Hooks hooks与fiber(workInProgress) 状态派发--useState(useReducer)原理 处理副作用--useEffect(useLayoutEffect ...

  5. react hooks使用_为什么要使用React Hooks?

    react hooks使用 The first thing you should do whenever you're about to learn something new is ask your ...

  6. 探React Hooks

    前言 众所周知,hooks在 React@16.8 中已经正式发布了.而下周周会,我们团队有个同学将会仔细介绍分享一下hooks.最近网上呢有不少hooks的文章,这不免激起了我自己的好奇心,想先行探 ...

  7. 使用React Hooks你可能会忽视的作用域问题

    前言 其实React Hooks已经推出来一段时间了,直到前一阵子才去尝试了下,看到的一些博客都是以API的使用居多,还有一些是对于原理的解析.而我这篇文章想写的是关于React Hooks使用中的作 ...

  8. 【译】什么是React Hooks

    原文:What are React Hooks? 作者:Robin Wieruch 译者:博轩 React Hooks 于 2018年10月的React Conf 中引入,作为在 React 函数组件 ...

  9. (十三)react hooks

    react hooks react hooks 出几道react hooks面试题 class组件存在哪些问题 用useState实现state和setState功能 用useEffect模拟组件生命 ...

最新文章

  1. 搭建免费ftp服务,视频演示
  2. matlab Lasso回归
  3. dubbo分布式事务解决方案_spring boot 分布式事务解决方案
  4. 【OpenGL】四、Visual Studio 2019 配置 GitHub ( 从 GitHub 上克隆项目 )
  5. DVWA 不跳转_渗透测试入门-DVWA应用渗透软件安装与使用
  6. NameNode之DataNode管理
  7. 多臂老虎机导论(一)引言
  8. 【Luogu1345】周游加拿大(动态规划)
  9. 判断用户输入的是数字还是字符串
  10. qq永久封号 代码_避免在代码中永久保留这些内容
  11. 南大Lamda实验室俞扬:我的牛年小结
  12. RAID 技术全解 – RAID0、RAID1、RAID5、RAID10
  13. 故障:ID29 的 KDC 警告日志
  14. SE5_FALSR超分辨率图像模型移植与测试
  15. Ubuntu16.04安装gazebo8并加载模型库
  16. Java课程设计-画图工具
  17. arduino(4):使用ESP8266,了解下相关芯片生产厂商,安信可的开发板子。
  18. 1631 小鲨鱼在51nod小学 暴力
  19. uAvionix 获得 FAA 批准进行 C 波段测试,并继续在几个新地点推出 SkyLine C2
  20. java silk v3 转码,小程序、录音、TP5、转码、silk

热门文章

  1. java技术架构选型方案报告.pdf,技术架构选型方案报告
  2. Rstudio常用操作
  3. 带薪年假执行调查8成员工抢休五六月 休息时间撞车
  4. 广州计算机中专学校大全,广州所有中专学校 中专学校名单
  5. unity 地图画格_unity游戏地形网格地图编辑生成插件Terrain Grid System v10.7
  6. 2023 年你还用 QQ 吗?
  7. 用递归法将一个整数n转换成字符串
  8. accordion(折叠面板)的使用
  9. 《给研究生的学术建议》4——导师
  10. 4分钟对拉300多次,谷歌用AI研发「乒乓球机器人」