前言:我在我的另一篇博客中有说道useEffect监听对象或者数组时会导致useEffect无限执行,并给予了解决方案-useEffect无限调用问题 .后来我想从其产生根源去理解并解决这个问题.

原因:

错误代码

 const [test, setTest] = useState({ name: '小明', age: '18' });
const init = () => {
setTest({ name: '小红', age: '16' });
};
useEffect(() => {
init();
console.log('kkk', test);
}, [test]);

以上代码,如果执行,会发现useEffect会无限执行.

分析原因有以下几个方面.

  1.引用数据类型的比较是地址,即"引用"来比较的.

   2.js每次创建对象都会产生一个新的地址.

简单来说就是

console.log({}==={})  //false

但是

let a = {}
let b = a
console.log(a===b) //true

也就是说,问题出在这行代码

 const init = () => {
setTest({ name: '小红', age: '16' });
};

这个{name:'小红',age:'16'}其实每次都是一个新的对象,在useEffect中比较的时候,每次都会拿到一个新的引用,所以useEffect每次都会执行,每次执行又拿到一个新的test.于是就变成了无限执行了.

解决方案:

所以我们可以用一下方案去避免这个问题的产生.

1.固定"引用".

即我们只用一个引用

let b = { name: '小明', age: '18' };
let a = { name: '小红', age: '16' };
const Test= () => {
const [test, setTest] = useState(b || { name: '小明', age: '18' }); //useState的默认值并不会更新,所以不会产生新引用
const init = () => {
setTest(a); //a的值不会变
};
useEffect(() => {
init();
console.log('kkk', test);
}, [test]);
}

2.固定"值"

即我们只要保证对象里面的属性和值是一样的就行

  const [test, setTest] = useState({ name: '小明', age: '18' });
const init = () => {
setTest({ name: '小红', age: '16' });
};
useEffect(() => {
init();
console.log('kkk', test);
}, [JSON.stringify(test)]); //只要对象里面的键和值是一样的,JSON.stringify(test)的值就不会变

应该还有其他方案,但大致方向就是这两类.

因为hooks的特性会导致组件代码重复执行,所以类似解构的默认值会重复给.假如使用的dva又不在models里面给默认值而是在hooks里给的话,监听这个变量就可能出现这个问题

const { btn={}} = useSelector((state) => state.buttonList);//假如buttonList里面btn并没有默认值,那这里监听btn就会出现useEffect多次进入的问题

hooks中,useEffect无限调用问题产生的原因的更多相关文章

  1. useEffect无限调用问题

    1.useEfect()的基本用法 const [test,setTest] = useState(1) const init=()=>{ setTest(2) } useEffect(()=& ...

  2. React Hooks中父组件中调用子组件方法

    React Hooks中父组件中调用子组件方法 使用到的hooks-- useImperativeHandle,useRef /* child子组件 */ // https://reactjs.org ...

  3. hooks中,useState异步问题解决方案

    问题描述: 在hooks中,修改状态的是通过useState返回的修改函数实现的.它的功能类似于class组件中的this.setState().而且,这两种方式都是异步的.可是this.setSta ...

  4. JavaScript 中的尾调用

    尾调用(Tail Call) 尾调用是函数式编程里比较重要的一个概念,它的意思是在函数的执行过程中,如果最后一个动作是一个函数的调用,即这个调用的返回值被当前函数直接返回,则称为尾调用,如下所示: f ...

  5. java 8中构建无限的stream

    目录 简介 基本使用 自定义类型 总结 java 8中构建无限的stream 简介 在java中,我们可以将特定的集合转换成为stream,那么在有些情况下,比如测试环境中,我们需要构造一定数量元素的 ...

  6. java中实现无限层级的树形结构

    本文展示了两个实现方法的代码.两个代码的实现方法不同,代码2更为简单. 先看一下最后实现的结果: 最后结果-json 代码1: 实现过程: 1.传入一段json字符串 2.将字符串转换成对象存入节点列 ...

  7. Hooks中的useState

    Hooks中的useState React的数据是自顶向下单向流动的,即从父组件到子组件中,组件的数据存储在props和state中,实际上在任何应用中,数据都是必不可少的,我们需要直接的改变页面上一 ...

  8. Java中是否可以调用一个类中的main方法?

    前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...

  9. 在IIS7.5中ASP.NET调用cmd程序拒绝访问决绝方法小记

    前言 昨天利用Github的Webhook实现自动部署站点,其中要调用命令行(cmd.exe)程序执行shell脚本. 在本地测试没有任何问题,部署到服务器之后,发现错误信息:访问拒绝. 问题 没有权 ...

随机推荐

  1. Nginx的try_files指令使用实例

    Nginx的配置语法灵活,可控制度非常高.在0.7以后的版本中加入了一个try_files指令,配合命名location,可以部分替代原本常用的rewrite配置方式,提高解析效率. try_file ...

  2. [bzoj5291]链上二次求和

    记$bi=b_{i-1}+ai$,$ci=c_{i-1}+bi$,那么答案就是$\sum_{i=l}^{r}\sum_{j=0}^{n-i}b_{j+i}-bj=(r-l+1)cn-\sum_{i=l ...

  3. JDK源码阅读(7):ConcurrentHashMap类阅读笔记

    ConcurrentHashMap public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implement ...

  4. 【Azure 应用服务】App Service 无法连接到Azure MySQL服务,报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

    问题描述 App Service使用jdbc连接MySQL服务,出现大量的  Communications link failure: com.mysql.cj.jdbc.exceptions.Com ...

  5. static关键字相关内容

    静态变量(static)与非静态变量,静态方法(static)与非静态方法 //static public class Student { private static int age; //静态的变 ...

  6. [NOI2020] 制作菜品

    看懂题目是生产第一要素. 考虑\(m = n - 1\)则必定有解.我们每次选择最小的和最大的拼在一起即可. 当\(m\)大于\(n\),那么我们只要每次选择最大的给他消掉即可. \(m = n - ...

  7. 【POJ3614 Sunscreen】【贪心】

    题面: 有c头牛,需要的亮度在[min_ci,max_ci]中,有n种药,每种m瓶,可以使亮度变为v 问最多能满足多少头牛 算法 我们自然考虑贪心,我们首先对每头牛的min进行排序,然后对于每种药,将 ...

  8. 洛谷 P4135 作诗(分块)

    题目链接 题意:\(n\) 个数,每个数都在 \([1,c]\) 中,\(m\) 次询问,每次问在 \([l,r]\) 中有多少个数出现偶数次.强制在线. \(1 \leq n,m,c \leq 10 ...

  9. Codeforces 856D - Masha and Cactus(树链剖分优化 dp)

    题面传送门 题意: 给你一棵 \(n\) 个顶点的树和 \(m\) 条带权值的附加边 你要选择一些附加边加入原树中使其成为一个仙人掌(每个点最多属于 \(1\) 个简单环) 求你选择的附加边权值之和的 ...

  10. Codeforces 715E - Complete the Permutations(第一类斯特林数)

    Codeforces 题面传送门 & 洛谷题面传送门 神仙题.在 AC 此题之前,此题已经在我的任务计划中躺了 5 个月的灰了. 首先考虑这个最短距离是什么东西,有点常识的人(大雾)应该知道, ...