HarmonyOSNext — V2()
Preface Previously, we discussed the decorators and key considerations for State Management V1, which are generally sufficient for most…
HarmonyOSNext — V2(1)
Preface Previously, we discussed the decorators and key considerations for State Management V1, which are generally sufficient for most development scenarios. However, there were still some areas of inconvenience, leading to the introduction of State Management V2. As of now, the V2 documentation has removed the “experimental” label, indicating it is stable for production use. The official recommendation is to migrate to V2 as soon as possible. Whether a V3 will be released in the future remains uncertain.
Overview The State Management V2 decorators, supported starting from API Level 12, include:
@ComponentV2: Defines custom components@ObservedV2and@Trace: Object observation@Local: Manages internal component state@Param: External input to components@Once: One-time initialization synchronization@Event: Standardizes component outputs@Providerand@Consumer: Cross-level bidirectional synchronization@Monitor: Listens for state variable changes@Computed: Defines computed properties
@ComponentV2
Similar to V1’s @Component, @ComponentV2 decorates custom components. It has the following constraints:
- Can only be used within classes decorated by
@ComponentV2. - Works exclusively with other V2 state management decorators.
- Mixing V1 and V2 decorators within the same component is not allowed.
@ComponentV2
struct Index {
build() {
}
}
@ObservedV2 and @Trace
Let’s start with these two decorators as they will be referenced when discussing other V2 features. These decorators enable deep observation, which means detecting changes in nested class properties. In V1, we used @Observed and @ObjectLink for this purpose, but they had a limitation: they could only observe property changes at the current level and not nested changes. With the combination of @ObservedV2 and @Trace in V2, you can now observe changes across multiple nested levels.
@ObservedV2
class Person {
@Trace name: string = ''
@Trace age: number = 0
@Trace address:Address = new Address()
}
@ObservedV2
class Address{
@Trace zipCode : string = '000000'
@Trace city:string = 'beijing'
}
When defining a nested class, use the @ObservedV2 decorator on the class that needs to be observed, and use @Trace to decorate each property that participates in UI rendering. This can become quite cumbersome when there are many classes and properties to observe.
Another extremely inconvenient and troublesome issue is that instances of classes decorated with @ObservedV2 currently do not support serialization using JSON.stringify.
@Local
The variables decorated with this decorator can only be initialized locally and cannot be passed in from the outside. This is designed to better represent the internal state of the component without being affected by external parameters.
Compared with @State, it cannot observe the assignment of properties in class objects and can only observe the overall assignment of objects. That is to say, its observation capability is limited to the decorated variable itself.
When it is necessary to observe changes in the properties of class objects, you need to use the @ObservedV2 and @Trace decorators.
One thing to note is that in State Management V2, a proxy layer is added to Date, Map, Set, and Array decorated with state variable decorators such as @Trace and @Local to observe changes caused by API calls. Therefore, when comparing the values inside, you need to use UIUtils.getTarget() to obtain the original object for comparison.
list: string[][] = [['a'], ['b'], ['c']];
@Local strList: string[] = this.list[0];
@Monitor("strList")
onStrChange(monitor: IMonitor) {
hilog.error(0x01, '@Local', 'strList has changed')
}
build() {
Column() {
Button('aa').onClick(() => {
if (this.strList !== this.list[0]) {
hilog.error(0x01, '@Local', 'aaa')
this.strList = this.list[0];
}
})
Button('bb').onClick(() => {
if (UIUtils.getTarget(this.strList) !== this.list[0]) {
hilog.error(0x01, '@Local', 'bb')
this.strList = this.list[0];
}
})
}
}
@Param
It can be passed in from the parent component or initialized locally. If used with @Require, the parent component must pass in this parameter, and the locally initialized value will be overwritten at this time.
One thing to note: you cannot directly modify the variable itself within the component, but you can modify the properties of the class object. If the properties of the class object are not decorated with @Trace, modifying the properties of the class object will not trigger a UI refresh.
When we directly modify the variable itself within the component, an error will be prompted: Cannot assign to ‘count’ because it is a read-only property.
메타데이터
- post_id
- 8000e83083c8
- slug
- harmonyosnext-v2-8000e83083c8
- url
- https://medium.com/@lhj18250199598/harmonyosnext-v2-8000e83083c8
- canonical_url
- https://medium.com/@lhj18250199598/harmonyosnext-v2-8000e83083c8
- author_url
- https://medium.com/@lhj18250199598
- status
- ok
- fetched_at
- 2026-07-25 17:06:40