Read the original article:State Management V2 in ArkTS : Observing Class Property Changes
Introduction
When developing mobile apps, handling state properly is one of those things that can make or break the user experience. ArkTS has made this easier and more powerful with State Management V2. Thanks to features like @ObservedV2 and @Trace, working with the state feels more natural, organized, and easier to follow.
In this article, I’ll walk you through how these new tools improve on what we had in State Management V1. I’ll also share how you can use them in your projects with practical code examples and tips.
If you’ve worked in the Mobile Ecosystem or you’re just starting with ArkTS, this guide will help you write cleaner, more responsive, and easier-to-debug apps using the latest tools ArkTS has to offer.
What is a State?
In simple terms, state refers to the data that determines what your app looks like and how it behaves at a given moment. It can be anything from a user’s login status, the value of a text input, the current page in a navigation flow, to whether a button is enabled or disabled.
Whenever this data changes, the UI usually needs to reflect those changes. That’s where state management comes in — it’s all about how we store, update, and react to those changes in a clean and predictable way.
What are the benefits of State Management V2?
With state management V1, properties of nested class objects are not directly observable.
@Observed
class Father {
son: Son;
constructor(name: string, age: number) {
this.son = new Son(name, age);
}
}
@Observed
class Son {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
@Entry
@Component
struct Index {
@State father: Father = new Father("John", 8);
build() {
Row() {
Column() {
Text(`name: ${this.father.son.name} age: ${this.father.son.age}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.father.son.age++;
})
}
.width('100%')
}
.height('100%')
}
}
In the preceding example, clicking the Text component increases the value of age, but does not trigger UI re-renders.
How do @ObservedV2 and @Trace work?
With State Management v2, when you use @ObservedV2 along with @Trace, the properties decorated with @Trace become observable. That means any changes to those properties automatically trigger a UI re-render, keeping the interface in sync with the underlying data.
1️⃣ Define an Observable Class
@ObservedV2
class Son {
@Trace age: number = 100;
}
2️⃣ Nesting Observable Data
class Father {
son: Son = new Son();
}
3️⃣ Build the Component
@Entry
@Component
struct Index {
father: Father = new Father();
4️⃣ UI Binding
build() {
Column() {
// If age is changed, the Text component is re-rendered.
Text(`${this.father.son.age}`)
.onClick(() => {
this.father.son.age++;
})
}
}
}
Conclusion
- The
Textcomponent displaysfather.son.age. - When you click the text,
ageis incremented. - Since
ageis@Trace-decorated and inside an@ObservedV2class, a change will be detected and automatically re-renders the UI.
🎯 No manual refresh needed. No boilerplate code. Just reactive, clean, and efficient.


Top comments (0)