HarmonyOS 鸿蒙Next 生命周期onPageShow初次进页面触发页面更新,返回时数据变视图未更新

发布于 1周前 作者 htzhanglong 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 生命周期onPageShow初次进页面触发页面更新,返回时数据变视图未更新

基本信息

export interface LangType {
  text: string
  status: boolean
  type: string
}
@Observed 
export class LangData {
  text: string
  status: boolean
  type: string

  constructor(obj:LangType) {
    this.text = obj.text
    this.status = obj.status
    this.type = obj.type
  }
}
@State 
langData:LangType[] = [
  new LangData({
    text:'简体中文',
    status:false,
    type:'zh-CN'
  }),
  new LangData({
    text:'English',
    status:false,
    type:'en-US'
  }),
  new LangData({
    text:'Deutsch',
    status:false,
    type:'de-DE'
  }),
  new LangData({
    text:'Italiano',
    status:false,
    type:'it-IT'
  }),
  new LangData({
    text:'Francais',
    status:false,
    type:'fr-FR'
  }),
  new LangData({
    text:'Espanol',
    status:false,
    type:'es-ES'
  })
]

这里在生命周期中执行的

langHandler(){
  // 判断当前语言
  let lang = AppStorage.get('language') as string
  let langItem = this.langData.find(item=>{
    return item.type === lang})
  console.log(`打印数据变化:${JSON.stringify(langItem)}`)
  if(langItem){
    this.langActive = langItem.text;
    console.log(`打印数据变化文字:${JSON.stringify(this.langActive)}`)
    return
  }
  this.langActive = this.langData[0].text;
}

打印结果也没有问题,数据触发了变化,但是视图就是没变

求大佬解答下


更多关于HarmonyOS 鸿蒙Next 生命周期onPageShow初次进页面触发页面更新,返回时数据变视图未更新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

15 回复

把langActive放在对象中传入RowList方法就可以了,也就是把你原来用的值传递改为引用传递。

值传递和引用传递可以用实际参数和形式参数的概念来帮助理解。

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。

引用传递:也可以说是传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。

这就和我们平常对一个方法传递一个数组,方法内部对这个数组进行操作,不返回这个数组,数组内部也会随之改变的道理相同。原理就是数据结构中基本类型和引用类型的区别,可以自己了解一下。

代码修改可以参考官方文档中的例子:

class Tmp {
  paramA1: string = '';
}

@Builder function overBuilder(params: Tmp) {
  Row() {
    Text(`UseStateVarByReference: ${params.paramA1} `)
  }
}
@Entry
@Component
struct Parent {
  @State label: string = 'Hello';
  build() {
    Column() {
      // 在父组件中调用overBuilder组件时,
      // 把this.label通过引用传递的方式传给overBuilder组件。
      overBuilder({ paramA1: this.label })
      Button('Click me').onClick(() => {
        // 单击Click me后,UI文本从Hello更改为ArkUI。
        this.label = 'ArkUI';
      })
    }
  }
}

更多关于HarmonyOS 鸿蒙Next 生命周期onPageShow初次进页面触发页面更新,返回时数据变视图未更新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


改成这个样子,数据还是没更新呢?,

  • 语言
    • 更换

看看是不是这个原因

调用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-builder-V13#按值传递参数

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17

  • 当状态变量被改变时,查询依赖该状态变量的组件;
  • 执行依赖该状态变量的组件的更新方法,组件更新渲染;
  • 和该状态变量不相关的组件或者UI描述不会发生重新渲染,从而实现页面渲染的按需更新。

你这种写法 @State修饰的变量 并没有绑定UI

UI部分代码:

RowList('语言', false, this.langActive, true, () => {
  router.pushUrl({
    url: 'pages/my/setting/lang'
  })
})
@Builder
function RowList(title: string, tag: boolean = false, text: string = '', borBottom: boolean = true,
  clickHandler: () => void) {
  Row() {
    Text(title).fontSize(14).fontColor('#857663').lineHeight(22)
    Row() {
      if (text) {
        Text(text).fontColor('#857663').fontSize(14).lineHeight(22).margin({ right: 6 })
        if (tag) {
          Text('更换')
            .fontSize(14)
            .lineHeight(22)
            .fontColor($r('app.color.subjectBg'))
            .onClick(() => clickHandler())
        }
      }
      if (!tag) {
        Image($r('app.media.right')).width(12).margin({ right: 4 })
      }
    }
  }
  .border({ width: { bottom: 1 }, color: borBottom ? '#66a69c92' : Color.Transparent })
  .padding({ bottom: 13, top: 12 })
  .width('100%')
  .justifyContent(FlexAlign.SpaceBetween)
  .onClick(() => {
    if (tag) {
      return
    }
    clickHandler()
  })
}

langActive变量是控制UI显示的不,加了@State

姓名

张三

职位

软件工程师

基本信息

  • 年龄: 30
  • 性别: 男
  • 所在地: 北京

技能

  • Java
  • Python
  • C++
  • HTML
  • CSS
  • JavaScript

工作经历

软件开发工程师 - ABC公司

2022年1月 - 至今

  • 负责项目的需求分析和设计
  • 编写高质量的代码并进行单元测试
  • 参与团队的技术讨论和分享

实习生 - XYZ公司

2020年7月 - 2021年6月

  • 协助完成项目的编码工作
  • 学习并实践敏捷开发流程
  • 与团队成员协作完成任务

教育背景

计算机科学与技术 - 本科

2016年9月 - 2020年7月

  • 毕业于北京大学
  • 主修课程:数据结构、操作系统、计算机网络等

-State langActive:string = ''

如果是Navigation做的导航,这个生命周期好像是只走一次的,可以打个断点,看生命周期到底进入了没有

生命周期进入了,第二次结果都打印出来了,只是UI没更新,

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17

你UI取的什么值啊

-State langActive:string = ‘’

针对HarmonyOS 鸿蒙Next 生命周期中onPageShow初次进页面触发页面更新,但返回时数据变化视图未更新的问题,可能的原因及解决方法如下:

在HarmonyOS中,onPageShow事件通常用于页面显示时的初始化或数据刷新。若初次进入页面时数据能够正确更新,但在返回该页面时数据变化未能同步到视图,可能是由于页面状态管理或数据绑定机制未正确处理。

可能的原因包括:

  1. 数据绑定未及时更新:确保数据变化后,通过适当的方式(如使用Observer模式或数据绑定框架)通知视图层进行更新。

  2. 页面缓存机制:若页面在返回时被缓存,且缓存策略未考虑数据更新,则可能导致视图层显示旧数据。检查页面的缓存策略,确保在返回页面时能够重新获取或刷新数据。

  3. 生命周期管理不当:在页面生命周期中,确保在适当的位置(如onPageShow或自定义的数据更新回调)触发数据刷新和视图更新。

解决方法:

  • 仔细检查数据绑定逻辑,确保数据变化能够触发视图更新。
  • 调整页面缓存策略,或在返回页面时手动触发数据刷新。
  • 优化页面生命周期管理,确保数据更新逻辑在正确的生命周期阶段执行。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部