HarmonyOS 更新数据后UI不刷新

@Entry
@Component
struct NavRootPage {
  @State rootData: RootData = new RootData()

  aboutToAppear(): void {
    this.rootData.textData = new TextData()
    this.rootData.textData.text = "1"
  }

  build() {
    Column() {

      CellRoot({ cellData: this.rootData })

      Button('change').onClick(() => {
        setTimeout(() => {
          for (let i = 0; i < 20; i++) {
            this.rootData.textData!.text = `${i}`
          }
        })
      })
    }
    .height('100%')
    .width('100%')
  }
}

@Builder
function TextCellBuilder() {
  TextCell()
}

@Observed
class RootData {
  builder: WrappedBuilder<[]> = wrapBuilder(TextCellBuilder)
  textData?: TextData
}

@Observed
class TextData {
  text?: string | Resource
}

@Component
struct CellRoot {
  @Provide cellData: RootData = new RootData()

  build() {
    this.cellData.builder.builder()
  }
}

@Component
struct TextCell {
  @Consume cellData: RootData

  build() {
    Column() {
      if (this.cellData.textData) {
        TextDemo({ data: this.cellData.textData })
      }
    }
  }
}

@Component
struct TextDemo {
  @ObjectLink data: TextData

  build() {
    Text(this.data.text)
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.

component和数据包含关系:CellRoot(provide cellData) -> TextCell(consume cellData) -> TextDemo(objectLink data from cellData)

CellRoot应用在列表上,为可复用组件

在ViewModel中创建数据

rootData = new RootData()
rootData.textData = new TextData()
rootData.textData.text = "1"
  • 1.
  • 2.
  • 3.

在处理了一些逻辑之后,手动设置

rootData.textData.text = "2"
  • 1.

UI偶现不刷新,尤其是频繁触发列表刷新的时候

HarmonyOS
2025-01-09 14:05:37
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
FengTianYa

请尝试在 @Reusable 组件中,重新赋值上层组件传递的数据

aboutToReuse(params: Record<string, RootData>): void {
  this.cellData = params.cellData; // 重新赋值
}
  • 1.
  • 2.
  • 3.

可参考如下demo:

本demo在provide、consume、objectLink层级修改数据UI层都可以正常刷新

let uid = 1;

export class MyDataSource<T = string> implements IDataSource {
  private list: T[] = [];

  constructor(list?: T[]) {
    if (list) {
      this.list = list;
    }
  }

  public pushData(data: T): void {
    this.list.push(data);
  }

  totalCount(): number {
    return this.list.length;
  }

  getData(index: number): T {
    return this.list[index]
  }

  registerDataChangeListener(): void {
  }

  unregisterDataChangeListener(): void {
  }
}

@Observed
class RootData {
  builder: WrappedBuilder<[]> = wrapBuilder(TextCellBuilder)
  textData?: TextData
}

@Observed
class TextData {
  text?: string | Resource;
  spanDataArray?: BaseData[]
}

@Observed
class BaseData {
  text?: string | Resource;

  constructor(text: string) {
    this.text = text;
  }
}

@Entry
@Component
struct Index {
  @State rootData: RootData = new RootData()
  @State list: MyDataSource<RootData> = new MyDataSource();

  aboutToAppear(): void {
    this.rootData.textData = new TextData()
    this.rootData.textData.text = "1";


    for (let i = 0; i <= 20; i++) {
      const rootData = new RootData();
      rootData.textData = new TextData();
      rootData.textData.text = `T${i}`;
      rootData.textData.spanDataArray = [new BaseData(`S${i}`)];
      this.list.pushData(rootData); // 0-20
    }
  }

  build() {
    Column() {
      Scroll() {
        Column() {
          CellRoot({ cellData: this.rootData });
          Button('change').onClick(() => {
            setTimeout(() => {
              for (let i = 0; i < 20; i++) {
                uid++;
                this.rootData.textData!.text = `T${uid}`;
              }
              this.rootData.textData!.spanDataArray = [new BaseData(`${uid}`)];
            })
          })

          List() {
            LazyForEach(this.list, (item: RootData) => {
              ListItem() {
                CellRoot({ cellData: item })
              }
              .width('100%')
              .height(100)
            }, (item: RootData) => JSON.stringify(item))
          }.cachedCount(5)
        }
      }

    }
    .height('100%')
    .width('100%')
  }
}


@Reusable
@Component
struct CellRoot {
  @Provide cellData: RootData = new RootData()

  aboutToReuse(params: Record<string, RootData>): void {
    console.log('aboutToReuse', this.getUniqueId())
    this.cellData = params.cellData; // 重新赋值
  }

  build() {
    Column() {
      Text(`Provide:${this.cellData.textData?.text}`)
        .onClick(() => {
          changeUid(this.cellData.textData as TextData);
        })
      this.cellData.builder.builder()
    }
  }
}

@Builder
function TextCellBuilder() {
  TextCell()
}

@Component
struct TextCell {
  @Consume cellData: RootData

  build() {
    Column() {
      Text(`Consume:${this.cellData.textData?.text}`)
        .onClick(() => {
          changeUid(this.cellData.textData as TextData);
        })
      TextDemo({ data: this.cellData.textData });
    }
  }
}

@Component
struct TextDemo {
  @ObjectLink data: TextData

  build() {
    Column() {
      Text(`Text:${this.data.text}`)
        .onClick(() => {
          changeUid(this.data);
        });
      ForEach(this.data.spanDataArray, (item: BaseData) => {
        Text(`spanText:${item.text}`)
      })
    }
  }
}

function changeUid(data: TextData) {
  uid++;
  console.log(`uid:${uid}`)
  const t = `${uid}`;
  data.text = t;
  data.spanDataArray = [new BaseData(t)];
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
分享
微博
QQ
微信
回复
2025-01-09 17:04:50
相关问题
【列表数据更新页面刷新
117浏览 • 1回复 待解决
IF条件变化UI刷新
1231浏览 • 1回复 待解决
HarmonyOS UI未在数据更新刷新
583浏览 • 1回复 待解决
HarmonyOS UI刷新
679浏览 • 1回复 待解决
修改ForEach使用的数据对象,UI刷新
2730浏览 • 1回复 待解决
HarmonyOS 卡片更新图片刷新
682浏览 • 1回复 待解决
HarmonyOS LIst组件UI刷新
421浏览 • 1回复 待解决
HarmonyOS UI刷新问题
663浏览 • 1回复 待解决
HarmonyOS @builder方法的ui刷新
985浏览 • 1回复 待解决
HarmonyOS使用@ObjectLink 数据刷新
1268浏览 • 2回复 待解决
状态装饰器 ui刷新的问题
2858浏览 • 1回复 待解决
HarmonyOS UI和ViewModel如何刷新数据
554浏览 • 1回复 待解决
HarmonyOS 下拉刷新的时候没有更新数据
1137浏览 • 1回复 待解决
HarmonyOS 懒加载列表更改属性UI刷新
567浏览 • 1回复 待解决
HarmonyOS 深色模式切换界面刷新
799浏览 • 1回复 待解决