1.useEfect()的基本用法

  1. const [test,setTest] = useState(1)
  2. const init=()=>{
  3. setTest(2)
  4. }
  5. useEffect(()=>{
  6. init()
  7. console.log('kkk',test)
  8. },[test])

红色'test'则是监听的数据,这里的监听数据要分为两种,1是基本数据类型,2是对象和数组

2.监听原理基本理解.

简单来说就是当修改后的值不同于修改之前就会执行.test默认为1,setTest()之后变成了2,又会执行init(),但是再次setTest()之后,test还是2,所以只会执行2次.一次默认,一次更改之后.

但是,当每次执行test都变化时将会无限次执行

  1. const [test,setTest] = useState(1)
  2. const init=()=>{
  3. setTest(test+1)
  4. }
  5. useEffect(()=>{
  6. init()
  7. console.log('kkk',test)
  8. },[test])

test每次更改都会和上次不一样,所以他会无限执行

3.监听对象和数组

当你在useEffect中监听对象或数组的时候,它会无条件无限执行.你可以理解为引用数据类型数据在赋值时每次都生成了一个新的数据.所以必定会执行.

故,不要把数组或者对象作为监听对象.

  1. //不能这么写
    const [test,setTest] = useState({name:'小明',age:'18'})
  2. const init=()=>{
  3. setTest({name:'小红',age:'16'})
  4. }
  5. useEffect(()=>{
  6. init()
  7. console.log('kkk',test)
  8. },[test])

解决方案:

如果我每次更改的就是对象,那我怎么监听.

1.标记法

同步更新一个可检测的数据,然后监听这个数据.

  1. const [test,setTest] = useState({name:'小明',age:'18'})
  2. const [index,setIndex] = useState(0)
  3. const init=()=>{
  4. setTest({name:'小红',age:'16'})
  5. setIndex(1)
  6. }
  7. useEffect(()=>{
  8. init()
  9. console.log('kkk',test)
  10. },[index])

这要求每个修改都必须要同步修改index,一次都不能少.相当于又引入了一个数据,还得自己全程盯着,流程多的时候可能会乱.不建议使用

2.加判断

假如我知道数据的走向,并且可以准确找到临界点.那我可以通过判断来掐断无限更新的流程

  1. const [test,setTest] = useState(1)
  2. const init=()=>{
  3. setTest(test+1)
  4. }
  5. useEffect(()=>{
  6. if(test!==2){
  7. init()
  8. console.log('kkk',test)
  9. }else{
  10.  
  11. }
  12. },[test])

3.对象属性监听

通过监听对象属性来判断对象变化,同时符合监听规则,不会无限执行

  1. const [test,setTest] = useState({name:'小明',age:'18'})
  2. const init=()=>{
  3. setTest({name:'小红',age:'16'})
  4. }
  5. useEffect(()=>{
  6. init()
  7. console.log('kkk',test)
  8.  
  9. },[test.name])

4.函数式赋值.

useState()可以通过返回返回值的方式赋值,在这个函数中可以拿到上次更改的state值,并且阻断useState自身

  1. const [test,setTest] = useState(1)
  2. const init=()=>{
  3. setTest((i)=>{
  4. if(i<2){
  5. console.log('???',i)
  6.  
  7. return i+1
  8. }else{
  9. return i
  10. }
  11. })
  12. }
  13. useEffect(()=>{
  14. init()
  15. console.log('kkk',test)
  16. },[test])

5.结合原因从根源上避开这个问题

具体的方案可访问我的另一篇博客:hooks中,useEffect无限调用问题产生的原因

useEffect无限调用问题的更多相关文章

  1. hooks中,useEffect无限调用问题产生的原因

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

  2. Shell脚本无限调用

    #! /bin/bash # this shell can run endlessfully echo "i love you ! " sh ./run 通过echo来显示了无限调 ...

  3. 无限调用函数add(1)(2)(3)......

    无限调用函数,并且累计结果 其实这也算一道面试题吧,笔者曾经被提问过,可惜当时没能答上来...

  4. javascript 函数 add(1)(2)(3)(4)实现无限极累加 —— 一步一步原理解析

    问题:我们有一个需求,用js 实现一个无限极累加的函数, 形如 add(1) //=> 1; add(1)(2)  //=> 2; add(1)(2)(3) //=>  6; add ...

  5. ionic上拉加载组件 ion-infinite-scroll自动调用多次的问题

    参考文章地址:http://www.cnblogs.com/luleixia/p/6402418.html ionic 一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面 ...

  6. 使用并发工具实现 RPC 调用流量控制

    前言 RPC 服务中,每个服务的容量都是有限的,即资源有限,只能承受住给定的网络请求,所以,在设计 RPC 框架的时候,一定要考虑流量控制这个问题.而 Java 中,实现流量控制有很多中方式,今天说 ...

  7. python中递归调用

    递归一个通俗的解释就是,在函数中调用函数本身:伪代码如下: In [31]: def fun(): ....: fun() # 这个递归没有任何作用,只是为了说明什么是递归 递归(Recursion) ...

  8. 解决ionic 上拉加载组件 ion-infinite-scroll自动调用多次的问题或禁止第一次加载

    ionic 中一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面高度,会自动检测并无限调用多次加载更多的函数: 当然,主要会导致首次调用的时候,会执行几次加载更多的函数: ...

  9. 解决ionic 上拉加载组件 ion-infinite-scroll自动调用多次的问题

    ionic 中一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面高度,会自动检测并无限调用多次加载更多的函数:当然,主要会导致首次调用的时候,会执行几次加载更多的函数: ...

随机推荐

  1. Python编程环境设置

    第1节.Python编程环境设置 一.sublime相关 1.sublime REPL插件安装 (1)安装 先打开插件安装面板:ctrl+shift+P 输入install ,选择Package Co ...

  2. [gym102978D]Do Use FFT

    前置知识 (以下内容并不严谨,可以参考论文<转置原理的简单介绍>) 对于一个算法,其为线性算法当且仅当仅包含以下操作: 1.$read\ i$,将$r_{i}$的值赋为(下一个)读入的元素 ...

  3. 使用postman对elasticsearch接口调用

    post 新增 get 查询 put更新 post http://127.0.0.1:9200/index4/type1 {"node":0} { "_index&quo ...

  4. C# Pechkin初始化一次后被锁住的问题

    Pechkin.dll可用于pdf的生成,常规用法网上都有介绍:https://www.cnblogs.com/felixnet/p/5143934.html 但是当在一个页面上执行过一次之后,再次就 ...

  5. Identity Server 4 从入门到落地(一)—— 从IdentityServer4.Admin开始

    最近项目中需要使用Identity Server 4,以前对这个技术只是有些了解,没有系统研究过,网上相关的资料不少,大多是从编写一个简单的认证服务开始,离能够落地使用有相当的距离,理论学习如何不结合 ...

  6. Go语言核心36讲(Go语言实战与应用十七)--学习笔记

    39 | bytes包与字节串操作(下) 在上一篇文章中,我们分享了bytes.Buffer中已读计数的大致功用,并围绕着这个问题做了解析,下面我们来进行相关的知识扩展. 知识扩展 问题 1:byte ...

  7. 【豆科基因组】小豆(红豆)adzuki bean, Vigna angularis基因组2015

    目录 一.来源 研究一:Draft genome sequence of adzuki bean, Vigna angularis 研究二:Genome sequencing of adzuki be ...

  8. 【R】行或列数目不同的两个数据框如何用rbind/cbind合并?

    目录 前言 方法一:dplyr的bind_rows 方法二:plyr的rbind.fill 前言 通常我们用rbind和cbind合并相同行列的数据框.当两个数据框具有不同行列数目时,直接用会报错. ...

  9. [R]在dplyr函数的基础上编写函数-(3)tidyeval

    dplyr的优点很明显,数据框操作简洁,如filter(df, x == 1, y == 2, z == 3)等于df[df$x == 1 & df$y ==2 & df$z == 3 ...

  10. 巩固javaweb第十七天

    巩固内容: 文本域 文本域主要用于输入多行文字,如果输入的文字比较多,则可以采用文本域. 文本域的基本格式如下: <textarea rows="行数" name=" ...