HarmonyOS 鸿蒙Next:@State 装饰对象时对对象属性赋值未触发页面刷新

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

HarmonyOS 鸿蒙Next:@State 装饰对象时对对象属性赋值未触发页面刷新

示例代码如下, didChangeState里面修改this.callSession.status的值,未触发页面刷新:

@Entry
@Component
export default struct SingleAudioCallPage {
    [@State](/user/State) targetUserInfo?: UserInfo = undefined
    [@State](/user/State) selfUserInfo?: UserInfo = undefined
    [@State](/user/State) state: number = 0
    [@State](/user/State) callSession?: CallSession = undefined

    aboutToAppear(): void {
        let callSession = avengineKit.currentSession;

        if (!callSession || callSession.status === CallState.STATUS_IDLE) {
            router.back()
            return
        }
        this.selfUserInfo = wfc.getUserInfo(wfc.getUserId())
        this.targetUserInfo = wfc.getUserInfo(callSession?.getParticipantIds()[0]!)

        this.state = callSession.status;
        this.callSession = callSession;
        this.setupSessionCallback()
    }

    setupSessionCallback() {
        let sessionCallback: CallSessionCallback = new CallSessionCallback()

        let that = this.callSession!;
        sessionCallback.didChangeState = (status: number) => {
            
            // 页面根据this.callSession.status进行布局,但此处更新this.callSession.status,不会触发 UI 刷新
            this.callSession!.status = status;
            this.state = status;
        }
        sessionCallback.didCallEndWithReason = reason => {
            router.back()
        }
        this.callSession!.sessionCallback = sessionCallback;
    }
    
    // ....
}

更多关于HarmonyOS 鸿蒙Next:@State 装饰对象时对对象属性赋值未触发页面刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

有找到除了强制更新的办法吗?

更多关于HarmonyOS 鸿蒙Next:@State 装饰对象时对对象属性赋值未触发页面刷新的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


  1. 有否尝试对callSession进行强制更新:tmp = callSession; callSession = null; callSession = tmp;

  2. 尝试换成@Observed@ObjectLink 看有无帮助。

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

我这边测试没问题

建议打印你的callSession是否真的存在实例。

class CallSession{
  status:number = 1
}

@Entry
@Component
struct Page71 {
  @State callSession?: CallSession = new CallSession();

  build() {
    Column(){
      Button(''+this.callSession?.status).onClick(()=>{
        console.info('测试1')
      })
      Button('测试2').onClick(()=>{
        // this.callSession = new CallSession()
        this.callSession!.status = 2
      })
    }.width('100%')
    .height('100%')
  }
}

callSession 确定存在的,打印callSession!.status 发现也变了,但页面未刷新。

和你上面的代码有一点不同的地方在于,触发更新 this.callSession!.status 的函数调用的 context。

你上面的代码,是通过 onClick 事件,然后触发,函数调用的 context 和页面的上下文其实是一个;
但我们的代码是通过 native 层的回调触发的更新,这时,函数调用的 context 和页面的上下文应当不是一个,我们上面代码,是通过箭头函数去处理这问题,

在HarmonyOS鸿蒙开发中,使用@State装饰对象时,如果对该对象的属性进行赋值而未触发页面刷新,这通常是因为状态管理的机制未正确应用。在鸿蒙的声明式UI框架中,@State用于标记组件的状态,当状态变化时,UI会自动重新渲染。

问题可能出在以下几个方面:

  1. 对象属性是否可观察:确保被@State装饰的对象属性是可观察的。如果属性是基本数据类型或符合鸿蒙状态管理要求的对象类型,通常能够触发更新。但如果是复杂对象且未正确实现观察者模式,则可能无法触发更新。

  2. 状态赋值方式:检查状态赋值是否在UI线程进行。鸿蒙框架要求状态更新必须在UI线程执行,否则可能导致更新不被触发。

  3. 对象引用问题:如果直接修改了对象的某个属性而没有改变对象的引用(即内存地址未变),鸿蒙可能无法检测到这种变化。尝试创建新的对象实例并赋值给状态变量,看是否能触发页面刷新。

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

回到顶部