HarmonyOS鸿蒙Next中@State状态发生变化但是Ui不更新

HarmonyOS鸿蒙Next中@State状态发生变化但是Ui不更新

@Entry @Component struct PersonInfoPage { @State birthDay: string = “1989-09-11”; dialog() { dialogDateSelect(“1940-01-01”, “2023-01-01”, this.birthDay, { onAccept(year, month, day) { this.birthDay = year + “-” + month + “-” + day; }, onCancel() {}, onChange(year, month, day) {} }); } build() { Row() { Text(“出生日期”).margin({ left: 15 }).fontColor(0x333333).fontSize(15) Blank().width(3) Text(this.birthDay) .fontColor(0x333333) .fontSize(15) .textAlign(TextAlign.End) .margin({ right: 5 }) .onClick((_) => { this.dialog(); }) Image($r(‘app.media.icon_right_arrows’)).width(8.5) .height(15).margin({ right: 15 }) } .width(‘100%’) .height(48) .justifyContent(FlexAlign.SpaceBetween) .alignItems(VerticalAlign.Center) .backgroundColor(0xffffff) } }

上面代码,我自定义了日期选择框,当用户点击出生日期时调用dialog函数弹出对话框选择出生日期,选择完成后能够执行onAccept回调函数,birthDay的值也发生了变化,但是Ui不更新,请问是怎么回事呢


更多关于HarmonyOS鸿蒙Next中@State状态发生变化但是Ui不更新的实战教程也可以访问 https://www.itying.com/category-93-b0.html

12 回复

原来的代码this的指向错了

更多关于HarmonyOS鸿蒙Next中@State状态发生变化但是Ui不更新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


明白了,onaccept函数中的this作用域变了,不是原来personinfo对象,所以无法更新,谢谢大佬。

看不到你自定义日期选择框的代码,可以换成如下代码:

@Entry
@Component
struct PersonInfoPage {
  @State birthDay:string="1989-09-11";
  dialog(){
    DatePickerDialog.show({
      start:new Date('1940-01-01'),
      end:new Date('2023-01-01'),
      selected:new Date(this.birthDay),
      onAccept:(value:DatePickerResult)=>{
        this.birthDay=value.year+'-'+(value.month+1)+'-'+value.day
      }
    })
  }
  build() {
    Row() {
      Text("出生日期").margin({ left: 15 }).fontColor(0x333333).fontSize(15)
      Blank().width(3)
      Text(this.birthDay)
        .fontColor(0x333333)
        .fontSize(15)
        .textAlign(TextAlign.End)
        .margin({ right: 5 })
        .onClick(( ) => {
          this.dialog()
        })
      Image($r('app.media.icon')).width(8.5)
        .height(15).margin({ right: 15 })
    }
    .width('100%')
    .height(48)
    .justifyContent(FlexAlign.SpaceBetween)
    .alignItems(VerticalAlign.Center)
    .backgroundColor(0xffffff)
  }
}

直接在当前页面使用dialog把DatePickerDialog封装成函数调用可以更新UI,抽取出来就不行,但是@state函数在当前页面进行的更新,不更新UI就很纳闷,

感谢大佬,

基本信息

这是深色代码主题

code here

这是正常代码主题

code here

@Entry @Component struct PersonInfoPage { @State birthDay:string=“1989-09-11”; build() { Column() { Text(“出生日期”).margin({ left: 15 }).fontColor(0x333333).fontSize(15) Blank().width(3) Text(this.birthDay) .fontColor(0x333333) .fontSize(15) .textAlign(TextAlign.End) .margin({ right: 5 }) .onClick(( ) => { //this.dialog() }) Button(‘改变子组件的内部值’).onClick(( )=>{ this.birthDay = ‘1111’; }) dialogDateSelect({birthDay: $birthDay}) } .width(‘100%’) .height(48) .justifyContent(FlexAlign.SpaceBetween) .backgroundColor(0xffffff) } }

@Component struct dialogDateSelect { @Link birthDay: string //装饰器 双向的 build() { Row() { Text(“出生日期:” + this.birthDay).margin({ left: 15 }).fontColor(0x333333).fontSize(15) Button(‘改变’).onClick(( )=>{ this.birthDay = ‘aa’; }) } } } 试下用Link

我想把DatePickerDialog封装成一个工具类,这样其他地方也可以传参直接使用。但是DatePickerDialog没有办法使用@Component做成组件,

直接在当前页面使用dialog把DatePickerDialog封装成函数调用可以更新UI,抽取出来就不行,但是@state函数在当前页面进行的更新,不更新UI就很纳闷,

export interface DateResultListener {
  onAccept?: (year: number, month: number, day: number) => void
  onCancel?: () => void
  onChange?: (year: number, month: number, day: number) => void
}

/**
 * @param startDate 填写开始时间 2000-1-1
 * @param endDate 结束时间 2100-12-31
 * @param selectedDate 选中时间 "2010-1-1"
 */
export function dialogDateSelect(startDate: string, endDate: string, selectedDate: string, listener: DateResultListener) {
  DatePickerDialog.show({
    start: new Date(startDate),
    end: new Date(endDate),
    selected: new Date(selectedDate),
    onAccept: (value: DatePickerResult) => {
      // 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期
      listener?.onAccept(value.year, value.month, value.day)
    },
    onCancel: () => {
      listener?.onCancel()
    },
    onChange: (value: DatePickerResult) => {
      listener?.onChange(value.year, value.month, value.day)
    }
  })
}

dialogDateSelect代码也贴上来

@param startDate 填写开始时间 2000-1-1
@param endDate 结束时间 2100-12-31
@param selectedDate 选中时间 “2010-1-1”

export function dialogDateSelect(startDate: string, endDate: string, selectedDate: string, listener: DateResultListener) { DatePickerDialog.show({ start: new Date(startDate), end: new Date(endDate), selected: new Date(selectedDate), onAccept: (value: DatePickerResult) => { // 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期 listener?.onAccept(value.year, value.month, value.day) }, onCancel: () => { listener?.onCancel() }, onChange: (value: DatePickerResult) => { listener?.onChange(value.year, value.month, value.day) } }) }

export interface DateResultListener { onAccept?: (year: number, month: number, day: number) => void onCancel?: () => void onChange?: (year: number, month: number, day: number) => void }

在HarmonyOS鸿蒙Next中,如果@State状态发生变化但UI未更新,可能原因及解决方法如下:

  1. 状态未触发重新渲染:确保状态变量确实被修改,且修改逻辑正确。
  2. UI组件未绑定状态:检查UI组件是否正确绑定了@State变量。
  3. 状态更新未在主线程:确保状态更新操作在主线程执行,避免异步操作导致UI未更新。
  4. 组件生命周期问题:检查组件生命周期,确保状态更新时组件处于活跃状态。
  5. 状态变量类型问题:确保状态变量类型是可观察的,如使用@Observed修饰。

通过以上步骤排查并修正问题,确保UI能正确响应状态变化。

回到顶部