react hooks使用useState修改引用类型的值,视图无法更新

4,896 阅读3分钟

react中使用useState修改对象或者数组的值无法改变视图

问题描述:

    return (
      <View>
        <View>
          {
            clinicPatientList.map((tag,index) => {
              return (
                <View key={index}>{tag.a}</View>
              )
            })
          }
        </View>
      </View>
    )

使用useState改变数组的值,dom没有更新:

66.png 1、第26、30行打印[ ]:因为setState是异步

useState异步,数据不能及时获取到

useState() 属于异步函数,在useState() 第一次存储的时候,值会存储不上。 因为react中state的更新是异步的,我们setState后,react不会立刻对值进行改变,而是将其暂时放入pedding队列中。react会合并多个state,然后值render一次,所以不要在循环中使用useState,它有可能只render最后一次set值,但是当传入一个函数时,函数就会被放入一个队列中,然后按照顺序执行。

解决方法:再写一个副作用Hook,只用于监视数组值的变化,从而进行操作

2、执行结果: 661.png 在定时器中修改State并重新setState后,值改变,但并未重新渲染(依然是3个数)。第二个useEffect没有执行。

原因:

React中默认浅监听,当变量为引用类型时,栈中存的是对象的引用(地址),setState改变的是堆中的数据

所以此时set后,栈中的地址还是原地址,React浅监听到地址没变,会认为State并未改变,所以没有重新渲染页面

1、解决方法: React中useState值为对象时改变值不渲染

改变栈中原arr所指向的地址:3种方式。

这里使用es6的拓展运算符,生成一个新的数组,地址发生了改变。

55.png 2、执行结果:

551.png 时间到了后,渲染的数从3个变成2个。

第二个useEffect也执行了:

当useEffect的项是引用类型时,React 会对比当前渲染下的依赖项clinicPatientList和上次渲染下的依赖项clinicPatientList的内存地址是否一致,如果一致,effect 不会执行,只有当对比结果不一致时,effect才会执行。

JS的基本类型和引用类型

基本类型:

基本类型的变量是存放在栈区的(栈区指内存里的栈内存), 栈区包括了 变量的标识符变量的值

1.jpg

var person1 = '{}';
var person2 = '{}';
console.log(person1 == person2); // true

引用类型:

(1)引用类型的值是按引用访问的。

(2)引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存 变量标识符 和 指向堆内存中该对象的指针(地址)

var person1 = {};
var person2 = {};
console.log(person1 == person2); // false

3.jpg

引用类型是按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同,那很明显,person1和person2在堆内存中地址是不同的。

引用类型变量的赋值:

var a = {}; // a保存了一个空对象的实例
var b = a; // a和b都指向了这个空对象
console.log(a == b);// true

a和b两个变量的值存的是相同的地址(指针),这两个指针指向了同一个对象。因此,改变其中任何一个变量指向的该对象,都会相互影响

4.jpg