useEffect无限调用问题
1.useEfect()的基本用法
const [test,setTest] = useState(1)
const init=()=>{
setTest(2)
}
useEffect(()=>{
init()
console.log('kkk',test)
},[test])
红色'test'则是监听的数据,这里的监听数据要分为两种,1是基本数据类型,2是对象和数组
2.监听原理基本理解.
简单来说就是当修改后的值不同于修改之前就会执行.test默认为1,setTest()之后变成了2,又会执行init(),但是再次setTest()之后,test还是2,所以只会执行2次.一次默认,一次更改之后.
但是,当每次执行test都变化时将会无限次执行
const [test,setTest] = useState(1)
const init=()=>{
setTest(test+1)
}
useEffect(()=>{
init()
console.log('kkk',test)
},[test])
test每次更改都会和上次不一样,所以他会无限执行
3.监听对象和数组
当你在useEffect中监听对象或数组的时候,它会无条件无限执行.你可以理解为引用数据类型数据在赋值时每次都生成了一个新的数据.所以必定会执行.
故,不要把数组或者对象作为监听对象.
//不能这么写
const [test,setTest] = useState({name:'小明',age:'18'})
const init=()=>{
setTest({name:'小红',age:'16'})
}
useEffect(()=>{
init()
console.log('kkk',test)
},[test])
解决方案:
如果我每次更改的就是对象,那我怎么监听.
1.标记法
同步更新一个可检测的数据,然后监听这个数据.
const [test,setTest] = useState({name:'小明',age:'18'})
const [index,setIndex] = useState(0)
const init=()=>{
setTest({name:'小红',age:'16'})
setIndex(1)
}
useEffect(()=>{
init()
console.log('kkk',test)
},[index])
这要求每个修改都必须要同步修改index,一次都不能少.相当于又引入了一个数据,还得自己全程盯着,流程多的时候可能会乱.不建议使用
2.加判断
假如我知道数据的走向,并且可以准确找到临界点.那我可以通过判断来掐断无限更新的流程
const [test,setTest] = useState(1)
const init=()=>{
setTest(test+1)
}
useEffect(()=>{
if(test!==2){
init()
console.log('kkk',test)
}else{ }
},[test])
3.对象属性监听
通过监听对象属性来判断对象变化,同时符合监听规则,不会无限执行
const [test,setTest] = useState({name:'小明',age:'18'})
const init=()=>{
setTest({name:'小红',age:'16'})
}
useEffect(()=>{
init()
console.log('kkk',test)
},[test.name])
4.函数式赋值.
useState()可以通过返回返回值的方式赋值,在这个函数中可以拿到上次更改的state值,并且阻断useState自身
const [test,setTest] = useState(1)
const init=()=>{
setTest((i)=>{
if(i<2){
console.log('???',i) return i+1
}else{
return i
}
})
}
useEffect(()=>{
init()
console.log('kkk',test)
},[test])
5.结合原因从根源上避开这个问题
具体的方案可访问我的另一篇博客:hooks中,useEffect无限调用问题产生的原因
useEffect无限调用问题的更多相关文章
- hooks中,useEffect无限调用问题产生的原因
前言:我在我的另一篇博客中有说道useEffect监听对象或者数组时会导致useEffect无限执行,并给予了解决方案-useEffect无限调用问题 .后来我想从其产生根源去理解并解决这个问题. 原 ...
- Shell脚本无限调用
#! /bin/bash # this shell can run endlessfully echo "i love you ! " sh ./run 通过echo来显示了无限调 ...
- 无限调用函数add(1)(2)(3)......
无限调用函数,并且累计结果 其实这也算一道面试题吧,笔者曾经被提问过,可惜当时没能答上来...
- javascript 函数 add(1)(2)(3)(4)实现无限极累加 —— 一步一步原理解析
问题:我们有一个需求,用js 实现一个无限极累加的函数, 形如 add(1) //=> 1; add(1)(2) //=> 2; add(1)(2)(3) //=> 6; add ...
- ionic上拉加载组件 ion-infinite-scroll自动调用多次的问题
参考文章地址:http://www.cnblogs.com/luleixia/p/6402418.html ionic 一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面 ...
- 使用并发工具实现 RPC 调用流量控制
前言 RPC 服务中,每个服务的容量都是有限的,即资源有限,只能承受住给定的网络请求,所以,在设计 RPC 框架的时候,一定要考虑流量控制这个问题.而 Java 中,实现流量控制有很多中方式,今天说 ...
- python中递归调用
递归一个通俗的解释就是,在函数中调用函数本身:伪代码如下: In [31]: def fun(): ....: fun() # 这个递归没有任何作用,只是为了说明什么是递归 递归(Recursion) ...
- 解决ionic 上拉加载组件 ion-infinite-scroll自动调用多次的问题或禁止第一次加载
ionic 中一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面高度,会自动检测并无限调用多次加载更多的函数: 当然,主要会导致首次调用的时候,会执行几次加载更多的函数: ...
- 解决ionic 上拉加载组件 ion-infinite-scroll自动调用多次的问题
ionic 中一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面高度,会自动检测并无限调用多次加载更多的函数:当然,主要会导致首次调用的时候,会执行几次加载更多的函数: ...
随机推荐
- vue.js学习与实战笔记(2)
驼峰式写法时需要注意的问题 学习到组件这一章时,由于没注意到vue中对于camelCased的解释,导致出错了都找不出来,后面发现 在使用驼峰式写法时,在使用模板的时候需要使用kebab-case命名 ...
- [nowcoder5669J]Jumping on the Graph
考虑枚举$k$并求出$f(k)=\sum_{i=1}^{n}\limits\sum_{j=i+1}^{n}\limits [D(i,j)\le k]$,那么答案就是$\sum_{i=1}^{1e9}( ...
- [nowcoder5668I]Sorting the Array
令$f(n,b,m)=a[1..n]$(这里下标从1开始),考虑一些性质: 性质1.对于$\forall 1\le i\le n-m+1$,若$\exists 1\le j<i,a[j]> ...
- 用图像识别玩Chrome断网小游戏
先来看一下效果 正文 最近在学习机器学习方面的知识,想着做个东西玩玩,然后就接触到了TensorFlow这个机器学习框架,这个框架封装了机器学习的一些常用算法. 不过要自己实现一套流程还是比较麻烦,我 ...
- 调试:'Object reference note set to an instance of an object.'
今天调试代码遇到一个奇怪的问题,每次调试到 var files = new List<string>()这一行代码,总是报错:System.NullReferenceException: ...
- 【知识详解】JAVA基础(秋招总结)
JAVA基础 目录 JAVA基础 问:面向过程(POP)和面向对象(OOP)? 问:Python和Java的区别? 问:java的八大基本数据类型? 问:封装继承多态说一下? 问:方法和函数的区别? ...
- Python+selenium定位一组元素,复选框
- SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表
读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...
- C++ and OO Num. Comp. Sci. Eng. - Part 3.
2. Expressions and Statements 声明是将一个种类型的变量引入程序的语句. 作用域 作用域又一对花括号限定,在所有花括号之外的为全局作用域. 在作用域内声明的变量为局部变量. ...
- R包开发过程记录
目的 走一遍R包开发过程,并发布到Github上使用. 步骤 1. 创建R包框架 Rsutdio --> File--> New Project--> New Directory - ...