用udeEffect // 深拷贝 --解决 useState 异步改变数据,数据更新不及时

   近期做tabs 切换时,发现由于useState 异步更新,导致tabs 显示的总是上一步的结果,简单记录一下解决方法。

一、 useEffect 解决

   1. useState 介绍

useState是让函数组件可以定义自己的state
useState调用会返回一个数组, 分别是变量和改变变量的方法
useState需要接收一个参数,是变量的初始值
useState改变数据是异步的

  2. useState 和 useRef 区别

 3. 异步更新问题

      如图,需要在切换tabs 时 显示对应的数据,但目前点击100米时,显示的是上一次点击的800米的数据,以下代码为点击tabs 的改变事件,

  const onChange = (key: string) => {
    // console.log('key》》',key);
    // key, 切换tabs 的值
    // newData, 切换tabs对应渲染的内容
    if (key === 'longJump') {
      setNewData(longJumpData)
    }
    if (key === 'solid') {
      setNewData(solidData)
    }
    if (key === 'eightHundred') {
      setNewData(eightHundredData)
    }
    if (key === 'oneHundred') {
      setNewData(oneHundredData)
    }
  };

  4. useEffect 介绍

 useEffect用于处理副作用,代替生命周期
 useEffect没有返回值,里面需要传入一个函数作为参数

 如果useEffect里面只传入了一个函数,相当于类组件的componentDidMount和componentDidUpdate
 useEffect还可以接收第二个参数,是一个数组(依赖数组)
 如果第二个参数是空数组,相当于类组件的componentDidMount
 如果第二个参数有内容,相当于vue的watch
 如果第一个函数参数里面返回一个函数,相当于类组件的componentWillUnmount

useEffect(() => {
    // getData().then((res) => {
    //   console.log(res);
    // });

    // todo 在useEffect里面使用async的方式请求封装好的接口,需要写函数自执行
    (async () => {
      const res = await getData();
      console.log(res);
    })();
  }, []);

 5. 用udeEffect 解决 useState 异步改变数据,数据更新不及时

useEffect(()=>{
    if (current === 'longJump') {
      setNewData(longJumpData)
    }
    if (current === 'solid') {
      setNewData(solidData)
    }
    if (current === 'eightHundred') {
      setNewData(eightHundredData)
    }
    if (current === 'oneHundred') {
      setNewData(oneHundredData)
    }
  },[current])
  
// tabs 的切换事件,key/current-tabs切换后的key
  const onChange = (key: string) => {
    setCurrent(key)
  };
  

二、 深拷贝解决

浅拷贝 基本类型之前互不影响,引用类型其中一个对象改变了地址,就会影响另一个对象; 改变新对象会使原数据一同改变

场景:添加数据,修改变量,页面更新不及时

错误写法:以下两种方法,其中一个是浅拷贝,引用了对象的地址,相当于两种都是修改了useState变量自身,用变量自身去push ,变量自身已经改变,再set时相当于没有变化,这个时候生命周期监听不到

  正确写法:深拷贝出来另一个数组 去改变数组  在set

import { cloneDeep } from 'lodash';

const handleOk = () => {

    addFacilityForm.validateFields()
      .then((values) => {
       
        const newFacilityList = cloneDeep(facilityList);

        newFacilityList.push(values)
      
        setFacilityList(newFacilityList)

      })
    setIsModalOpen(false);
  };

猜你喜欢

转载自blog.csdn.net/weixin_65969505/article/details/128097227