HarmonyOS鸿蒙Next中@State数组无法触发重绘

HarmonyOS鸿蒙Next中@State数组无法触发重绘 无法触发重绘? 但是可以获取到变更的值,页面无变化

对象

export class ObjectA{
    a1: string,
    a2: number,
    a3: Date
    ...
}

组件入口

@Entry
@Component
struct ComponentA {

    [@State](/user/State)
    array1: Array<ObjectA> = []

    builc(){
        Tabs(){
            TabContent(){
                ComponentB({array1: array1})
            }
        }
    }
    
}

子组件ComponentB

@Component
struct ComponentB {
    
    @Link
    array1: Array<ObjectA>

    builc(){
        Column(){
            // 这个地方有刷新,数据有变更
            Text(JSON.stringify(this.array1))
            
            // 这个地方没有刷新,但是可以获取到新的数据
             List(){
                ForEach(this.array1, (obj: ObjectA, index: number) => {
                  ListItem() {
                    this.listItem(obj, index)
                  }
                  
                }, (obj: ObjectA) => obj.a1)
            }
        }
       
    }
}

更多关于HarmonyOS鸿蒙Next中@State数组无法触发重绘的实战教程也可以访问 https://www.itying.com/category-93-b0.html

14 回复

只有更改obj.al才会重新渲染,因为这个是你的主键

更多关于HarmonyOS鸿蒙Next中@State数组无法触发重绘的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


应该是这样的,我仔细重读了文档,看到的与你说的一样,今晚回去试试,

已验证,确实是foreach的key出了问题导致的,

其实正常写法不应该是list传入子组件,应该是在父组件循环然后子组件渲染item,item如果是对象则使用@ObjectLink装饰.

我是重新赋值了就可以更新了,但感觉很别扭

cke_163.png

直接this.array1= [...this.array1];就可以触发更新了

我想我应该知道是什么原因了,仔细阅读文档,发现foreach刷新的条件就是当key发生改变才能认为是组件更新,那这样如果是对象需要实时更新,就不应该使用里边的某个属性作为key,而是每次得生成一个唯一数据,让foreach感知到变化,而不仅仅是创建一个新对象,可以采用默认的key生成方式“index+JSON(item)”——待验证,

你不能只去修改array1里某个字段的值,而是最后要重新设置array1,可以理解为重新给array1赋值

HarmonyOS的社区里有很多技术大牛分享经验,学到了很多有用的知识。

是的,我的数据是通过rdb获取,然后重新使用new构建一个对象,但是确实没有发生改变。

值得一提的是,新增item可以新增,但是变更的item没有发生变化,不知道哪里出了问题。

我一般是定义一个新的对象,然后让他等于原来的对象,再在新的对象里修改,把新的对象赋值给那个array1。

在HarmonyOS鸿蒙Next中,[@State](/user/State)装饰器用于标记状态变量,当状态变量发生变化时,系统会自动触发UI重绘。然而,如果[@State](/user/State)修饰的是一个数组,直接修改数组的内容(如通过pushsplice等方法)可能无法触发重绘。这是因为[@State](/user/State)装饰器检测的是数组引用的变化,而不是数组内部元素的变化。

要解决这个问题,可以通过以下方式强制触发重绘:

  1. 重新赋值数组:在修改数组内容后,重新赋值给[@State](/user/State)变量。例如:

    this.myArray = [...this.myArray, newElement];
    
  2. 使用[@Observed](/user/Observed)@ObjectLink:如果数组中的元素是对象,可以使用[@Observed](/user/Observed)@ObjectLink装饰器来监听对象属性的变化。例如:

    [@Observed](/user/Observed)
    class MyObject {
      // 对象属性
    }
    
    [@State](/user/State) myArray: MyObject[] = [];
    
    // 修改对象属性后,UI会自动重绘
    
  3. 使用[@Link](/user/Link):如果数组是从父组件传递下来的,可以使用[@Link](/user/Link)装饰器来监听数组的变化。例如:

    [@Link](/user/Link) myArray: MyObject[];
    

通过这些方法,可以确保在数组内容发生变化时,UI能够正确重绘。

在HarmonyOS鸿蒙Next中,@State装饰器用于标记状态变量,当状态变化时会触发UI重绘。如果@State数组无法触发重绘,可能是以下原因:

  1. 数组引用未改变:@State依赖引用变化来触发重绘。如果直接修改数组内容(如pushsplice),数组引用未变,不会触发重绘。应使用新数组替换原数组,如this.array = [...this.array, newItem]

  2. 未正确使用@State:确保@State装饰器正确应用在组件类中,且数组是组件的状态变量。

  3. UI未绑定状态:确保UI组件正确绑定了@State数组,如使用ForEachList组件。

  4. 组件生命周期问题:检查组件生命周期,确保状态更新发生在组件挂载后。

通过确保数组引用变化和正确绑定,可以解决@State数组无法触发重绘的问题。

回到顶部