测试之前项目中关于useEffect的疑惑

1.监听组件自己的数据

第一种:组件内数据不发生改变,react自带的diffling算法,起了作用,页面不刷新,回调也不会执行

import React, { useEffect, useState } from 'react'

export default function C() {
    const [num,setNum] = useState(0);
    useEffect(()=>{
        console.log("我被执行了");
    })
    const add1 = ()=>{
        setNum(num)
    }
  return (
    <div>
      <input type="text" placeholder={num}/>
      <button onClick={()=>add1()}>+1</button>
    </div>
  )
}

 

 第二种:第二参数啥也不写,只要组件里面num变了:useEffect中的回调一直执行;页面一直刷新,刷新也就意味着再一直渲染

import React, { useEffect, useState } from 'react'

export default function C() {
    const [num,setNum] = useState(0);
    useEffect(()=>{
        console.log("我被执行了");
    })
    const add1 = ()=>{
        setNum(num+1)
    }
  return (
    <div>
      <input type="text" placeholder={num}/>
      <button onClick={()=>add1()}>+1</button>
    </div>
  )
}

 

 第三种:useEffect第二参数是一个[],只要组件内数据num改变,只执行一次回调,之后不再执行该回调;页面一直渲染,

import React, { useEffect, useState } from 'react'

export default function C() {
    const [num,setNum] = useState(0);
    useEffect(()=>{
        console.log("我被执行了");
    },[])
    const add1 = ()=>{
        setNum(num+1)
    }
  return (
    <div>
      <input type="text" placeholder={num}/>
      <button onClick={()=>add1()}>+1</button>
    </div>
  )
}

 

 第四种:useEffect第二参数是num依赖,即[num],只要num改变,就会执行回调,否则不执行回调;页面一直刷新;当第一次数据改变之后,比如+1后,num=2,进行setNum后,useEffect回调不执行,但是页面刷新一次,此后执行该操作,页面将不再刷新,除非num改变,会再出现"页面刷新一次,此后执行该操作,页面将不再刷新"。

import React, { useEffect, useState } from 'react'

export default function C() {
    console.log(111)
    const [num,setNum] = useState(0);
    useEffect(()=>{
        console.log("我被执行了");
    },[num])
    const add1 = ()=>{
        setNum(num+1)
    }
    const shuaxin = ()=>{
        setNum(num)
    }
  return (
    <div>
      <input type="text" placeholder={num}/>
      <button onClick={()=>add1()}>+1</button>
      <button onClick={()=>shuaxin()}>刷新</button>
    </div>
  )
}

监听自己的组件的数据总结:

  1. 首先整个组件内数据不变,useEffect回调、页面刷新只执行一次
  2. 整个组件内数据先发生改变,回调一次页面刷新一次,随后不变,回调不执行,页面刷新一次,也就是说,只要整个组件内数据发生改变,页面一直刷新,回调看第二参数
  3. 控制第二参数,不写,整个组件只要有数据改变,就执行回调;为【】,无论数据改变,回调只执行一次;为【num】监听num,只针对num变,回调就执行

2.不同页面,监听组件外来数据

2.1 监听location.state

当D点击+1,再navigate跳转到C,C接收传来的location

C组件中现有变量:location.state,num

  1. 首先无关数据,跳转后。被跳转页面C默认先渲染一次、执行一次useEffect的回调函数;
  2. 如果外来数据没有修改本地状态,那么页面只有默认渲染一次、执行回调一次;
  3. 如果外来数据修改了本地状态,那么刚跳转近来,页面默认渲染一次、执行回调一次;
    1. 第二参数不写与【num】效果类似,但一个是全局数据,一个是针对怒骂,本地数据被改变了,再渲染一次、执行一次回调;然后再渲染一次;这是因为num被改变页面检测到本地数据被修改,
    2. 第二参数写【】与【location.state】,页面刷新,不执行回调

总结:

页面跳转,默认刷新一次,执行回调一次;而后看第二参数,

数据改变必刷新,useEffect不写第二参数,回调必执行;第二参数只要监听变的那个数,数变则回调必执行;第二参数[],无论哪个数变,只执行一次;

 

最终总结:

    const [num3,setNum3] = useState(1);
    const location = useLocation();
    console.log("我被刷新了2", location.state)
    useEffect(()=>{
        console.log("我被zhixingle了", location.state)
        setNum3(location.state)
    },[])

页面重新刷新(例如手动刷新、或者页面跳转导致页面重新渲染),必然执行一次行其他语句(前3行代码)、回调(useEffect第一参数)

第二参数不写时,组件内只要有数据改变,其他代码、回调都会执行一次

第二参数为【XXX】,XXX(组件内部变量),XXX改变一次,其他代码、回调都会执行一次;XXX未改变,只会执行其他代码

第二参数为【】,回调只在页面第一次渲染时执行一次,往后无论数据变化,都是 其他代码 在执行时第一次会出现:数据变动一次,其他代码执行2次,再之后,动一次,其他代码执行一次。

当监听消息订阅发布时,不同页面之间是不符合正常规律的,若是添加返回值来去除负效应,页面跳转后,产生了新的token即uid,导致接收不到数据,进不到订阅的回调,如果不加返回值,那么每次就会产生+2个token的情况,因此消息订阅与发布最好用在同一页面不同组件之间,当一个发布数据的时候,另一个组件不是跳转页面过去的,如果把一个页面当一家人,那么亲兄弟的订阅发布与useEffect才是有效监听。亲戚家的就算了。复杂的消息共享,redux更实用,后面我会对redux进行一次test,做个例子。

posted @ 2022-08-30 12:00  乔十六  阅读(192)  评论(0编辑  收藏  举报