HarmonyOS 状态变量不刷新问题

下面这段代码在点击每个Item删除数组元素时,问什么没刷新到UI上。

//状态变量问题  
class Article {  
  id: string;  
  title: string;  
  brief: string;  
  constructor(id: string, title: string, brief: string) {  
    this.id = id;  
    this.title = title;  
    this.brief = brief;  
  }  
}  
class Arrtest{  
  articleList: Array<Article> = [  
    new Article('001', '第1篇文章', '文章简介内容'),  
    new Article('002', '第2篇文章', '文章简介内容'),  
    new Article('003', '第3篇文章', '文章简介内容'),  
    new Article('004', '第4篇文章', '文章简介内容'),  
    new Article('005', '第5篇文章', '文章简介内容'),  
    new Article('006', '第6篇文章', '文章简介内容')  
  ]  
}  
@Entry  
@Component  
struct ArticleListView {  
  @State isListReachEnd: boolean = false;  
  @State arrtest: Arrtest = new Arrtest()  
  
  build() {  
    Column({ space: 5 }) {  
      Flex() {  
        ForEach(this.arrtest.articleList, (item: Article, index: number) => {  
          ListItem() {  
            this.articleCard(index)  
          }  
        }, (item: Article) => item.id)  
      }  
      .padding(20)  
    }  
    .width('100%')  
    .height('100%')  
    .backgroundColor(0xF1F3F5)  
  }  
  
  @Builder  
  articleCard(index: number) {  
    Row() {  
      Column() {  
        Text('test')  
          .fontSize(20)  
          .margin({ bottom: 8 })  
      }  
      .alignItems(HorizontalAlign.Start)  
      .width('80%')  
      .height('100%')  
    }  
    .padding(20)  
    .borderRadius(12)  
    .backgroundColor('#FFECECEC')  
    .height(120)  
    .width('100%')  
    .justifyContent(FlexAlign.SpaceBetween)  
    .onClick(() => {  
      this.arrtest.articleList?.splice(index, 1)  
    })  
}  
}
HarmonyOS
2024-09-27 13:16:10
浏览
收藏 0
回答 2
待解决
回答 2
按赞同
/
按时间
鱼弦CTO
1

在 HarmonyOS 中,如果状态变量的更改没有正确地刷新 UI,很可能是因为状态管理或者数据绑定的问题。你的代码中,使用了 ​​@State​​ 装饰器来声明状态变量,但操作数组的方法可能没能通知框架当前状态发生了变化。

## 问题分析

### 1. 数组操作 直接操作数组(如 ​​splice​​)不会触发对整个对象属性的变动通知。框架可能无法检测到数组内容的变化,从而不重新渲染组件。

### 2. 确保状态更新 需要确保每次更改数组数据时,能够通知框架状态已经改变。

## 改进方法

### 使用 ​​@State​​ 和 ​​@Link​

  • @State
  • @Link

### 示例代码

以下是如何改进你的代码,以确保在删除数组元素时能够正确地刷新 UI:

// 状态变量问题
class Article {  
  id: string;  
  title: string;  
  brief: string;  
  constructor(id: string, title: string, brief: string) {  
    this.id = id;  
    this.title = title;  
    this.brief = brief;  
  }  
}  

class Arrtest{  
  articleList: Array<Article> = [  
    new Article('001', '第1篇文章', '文章简介内容'),  
    new Article('002', '第2篇文章', '文章简介内容'),  
    new Article('003', '第3篇文章', '文章简介内容'),  
    new Article('004', '第4篇文章', '文章简介内容'),  
    new Article('005', '第5篇文章', '文章简介内容'),  
    new Article('006', '第6篇文章', '文章简介内容')  
  ]  
}  

@Entry  
@Component  
struct ArticleListView {  
  @State isListReachEnd: boolean = false;  
  @State arrtest: Arrtest = new Arrtest()  
  
  build() {  
    Column({ space: 5 }) {  
      Flex() {  
        ForEach(this.arrtest.articleList, (item: Article, index: number) => {  
          ListItem() {  
            this.articleCard(index)  
          }  
        }, (item: Article) => item.id)  
      }  
      .padding(20)  
    }  
    .width('100%')  
    .height('100%')  
    .backgroundColor(0xF1F3F5)  
  }  
  
  @Builder  
  articleCard(index: number) {  
    Row() {  
      Column() {  
        Text('test')  
          .fontSize(20)  
          .margin({ bottom: 8 })  
      }  
      .alignItems(HorizontalAlign.Start)  
      .width('80%')  
      .height('100%')  
    }  
    .padding(20)  
    .borderRadius(12)  
    .backgroundColor('#FFECECEC')  
    .height(120)  
    .width('100%')  
    .justifyContent(FlexAlign.SpaceBetween)  
    .onClick(() => {  
      this.handleItemClick(index);  
    })  
  }
  
  handleItemClick(index: number) {
    // 刷新数据
    let newArray = [...this.arrtest.articleList]; // 创建数组副本
    newArray.splice(index, 1); // 在副本上操作
    this.arrtest.articleList = newArray; // 重新赋值触发更新
  }
}

### 关键点解释:

  1. 创建数组副本:
  • 使用 ES6 展开运算符​​...​​ 创建一个数组的副本。
  • 在副本上进行​​splice​​ 操作,这样可以避免原数组的直接修改。
  1. 重新赋值:
  • 将修改后的数组副本重新赋值给状态变量​​this.arrtest.articleList​​。
  • 重新赋值操作会触发状态更新,并使得 UI 重新渲染。

通过这种方式,可以确保状态变量的更改能够被框架正确检测到,从而刷新 UI。如果有进一步的问题或特殊需求,请随时提问。

分享
微博
QQ
微信
回复
2024-09-28 16:11:40
put_get

可参考如下关键代码:

.onClick(() => {  
  this.arrtest.articleList?.splice(index, 1);  
  this.arrtest.articleList = this.arrtest.articleList.concat([]);  
})
分享
微博
QQ
微信
回复
2024-09-27 17:34:25
相关问题
状态变量和常规变量有什么区别?
382浏览 • 2回复 待解决
ArkTS中如何监听状态变量的变化?
847浏览 • 1回复 待解决
关于状态变量@state必须知道的事
1004浏览 • 1回复 待解决
HarmonyOS 列表刷新问题
472浏览 • 1回复 待解决
HarmonyOS 页面刷新问题
217浏览 • 1回复 待解决
HarmonyOS List item 刷新问题
649浏览 • 1回复 待解决
状态装饰器 ui刷新问题
2347浏览 • 1回复 待解决
HarmonyOS使用Refresh下拉刷新问题
702浏览 • 1回复 待解决
HarmonyOS 组件的下拉刷新问题
377浏览 • 1回复 待解决
HarmonyOS UI 未刷新问题
366浏览 • 0回复 待解决
HarmonyOS 页面跳转刷新问题
623浏览 • 1回复 待解决
NativeWindowFlushBuffer接口刷新问题
1919浏览 • 1回复 待解决
HarmonyOS 二维数组刷新问题
185浏览 • 1回复 待解决