DEV Community

Cover image for HarmonyOS Development: V2 Version Decorator @ Once
程序员一鸣
程序员一鸣

Posted on

HarmonyOS Development: V2 Version Decorator @ Once

Foreword

this article code case based on api13.

Recently, when preparing to upgrade the decorator of refresh refresh Library from V1 to V2, I encountered a problem and switched the @ Prop decorator. When the @ Param decorator found that the properties of the custom component could not be modified, the prompt reported an error:

Cannot assign to 'testContent' because it is a read-only property. <ArkTSCheck>
Enter fullscreen mode Exit fullscreen mode

actual error screenshot:

Image description

the cause of the error is that the variable decorated with @ Param only supports local initialization and cannot be directly modified inside the component.

Although we know the reason, due to the logic of V1 version, in addition to the transmission from the caller in the custom component, its own attributes also need to be dynamically modified, otherwise the amount of changes will be very large, and when we are looking for other methods to implement it, the @ Once decorator came into view.

What is the @ Once decorator

as an auxiliary decorator, the @ Once decorator itself does not require decoration types and the ability to observe variables, but it has two functions. The first is to solve the problem that the attributes modified by the @ Param decorator cannot be modified. The second is to realize the ability to initialize only Once from the outside and not accept subsequent Synchronization changes, that is, when subsequent data source changes, the changes will not be synchronized to subcomponents.

One thing to note, that is. The @ Once decorator cannot be used alone, must use with @ Param when used in combination, it will not affect the observation capability of @ Param. It will only intercept changes in the data source, and it will not affect who is in front and who is behind.

When used together, the front and rear positions can be:

@Param @Once testContent: string = "test 1"
@Once @Param testContent2: string = "test 2"
Enter fullscreen mode Exit fullscreen mode

use Scenario

if we only use @ Param decoration to decorate, we will find that the caller will cause the custom component data to change as long as the data changes. If you want to only initialize the incoming data to synchronize, and then the data changes need not be synchronized, then you can use @ Once decorator to decorate. After modification, no matter how you modify it, it will not cause data changes.

@ComponentV2
struct RefreshLayout {
  @Param @Once testContent: string = "test 1"

  build() {
    Column() {
      Text(this.testContent)
    }
  }
}

@Entry
@ComponentV2
struct Index {
  @Local testContent: string = "Hello World"

  build() {
    Column() {
      RefreshLayout({ testContent: this.testContent })
      Button("click")
        .margin({ top: 20 })
        .onClick(() => {
          this.testContent = "test 2"
        })
    }.width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}
Enter fullscreen mode Exit fullscreen mode

The above situation is that the external caller updates and does not want to cause data changes to the custom component. If you want to use @ Param to modify the attributes inside the custom component, you can change them and update the UI, then you can use @ Once decorator to modify them.

@ComponentV2
struct RefreshLayout {
  @Param @Once testContent: string = "test 1"

  build() {
    Column() {
      Text(this.testContent)
      Button("click")
        .margin({ top: 20 })
        .onClick(() => {
          this.testContent = "test 2"
        })
    }
  }
}

@Entry
@ComponentV2
struct Index {
  @Local testContent: string = "Hello World"

  build() {
    Column() {
      RefreshLayout({ testContent: this.testContent })
    }.width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}
Enter fullscreen mode Exit fullscreen mode

Related Summary

the @ Once decorator can only be used with @ Param. This is the only combination and there is no other way to use it. Also, it must be in V2 version, that is, the custom component decorated by @ ComponentV2, otherwise an exception will be reported.

The following in combination with other decorators is a case of error:

 @Local @Once testContent: string = "Hello World"
Enter fullscreen mode Exit fullscreen mode

an error exception will be reported:

'@Once' works only when used with '@Param' in pairs. <ArkTSCheck>
Enter fullscreen mode Exit fullscreen mode

the abnormal screenshot is as follows:

Image description

Top comments (0)