1# \@State: State Owned by Component 2 3 4An \@State decorated variable, also called a state variable, is a variable that holds the state property and is used to render the owning custom component. When it changes, the UI is re-rendered accordingly. 5 6 7Among the decorators related to state variables, \@State is the most basic decorator, as it is the one that empowers variables to have the state property. It is also the data source of most state variables. 8 9 10> **NOTE** 11> 12> Since API version 9, this decorator is supported in ArkTS widgets. 13 14 15## Overview 16 17An @State decorated variable, like all other decorated variables in the declarative paradigm, are private and only accessible from within the component. Its type and its local initialization must be specified. Initialization from the parent component using the named parameter mechanism is accepted. 18 19\@State decorated variables have the following features: 20 21- A one-way and two-way data synchronization relationship can be set up from an \@State decorated variable to an \@Prop, \@Link, or \@ObjectLink decorated variable in a child component. 22 23- The lifecycle of the \@State decorated variable is the same as that of its owning custom component. 24 25 26## Rules of Use 27 28| \@State Decorator| Description | 29| ------------ | ---------------------------------------- | 30| Decorator parameters | None. | 31| Synchronization type | Does not synchronize with any type of variable in the parent component. | 32| Allowed variable types | Object, class, string, number, Boolean, enum, and array of these types. For details about the scenarios of nested types, see [Observed Changes](#observed-changes).<br>The type must be specified.<br>**any** is not supported. A combination of simple and complex types is not supported. The **undefined** and **null** values are not allowed.<br>**NOTE**<br>Avoid using this decorator to decorate the Date type, as doing so may lead to unexpected behavior of the application.<br>The Length, ResourceStr, and ResourceColor types are a combination of simple and complex types and therefore not supported.| 33| Initial value for the decorated variable | Mandatory. | 34 35 36## Variable Transfer/Access Rules 37 38| Transfer/Access | Description | 39| --------- | ---------------------------------------- | 40| Initialization from the parent component | Optional. Initialization from the parent component or local initialization can be used.<br>An \@State decorated variable can be initialized from a regular variable or an \@State, \@Link, \@Prop, \@Provide, \@Consume, \@ObjectLink, \@StorageLink, \@StorageProp, \@LocalStorageLink, or \@LocalStorageProp decorated variable in its parent component.| 41| Subnode initialization | Supported. An \@State decorated variable can be used to initialize a regular variable or \@State, \@Link, \@Prop, or \@Provide decorated variable in the child component.| 42| Access| Private, accessible only within the component. | 43 44 **Figure 1** Initialization rule 45 46![en-us_image_0000001502091796](figures/en-us_image_0000001502091796.png) 47 48 49## Observed Changes and Behavior 50 51Not all changes to state variables cause UI updates. Only changes that can be observed by the framework do. This section describes what changes can be observed and how the framework triggers UI updates after the changes are observed, that is, how the framework behaves. 52 53 54### Observed Changes 55 56- When the decorated variable is of the Boolean, string, or number type, its value change can be observed. 57 58 ```ts 59 // for simple type 60 @State count: number = 0; 61 // value changing can be observed 62 this.count = 1; 63 ``` 64 65- When the decorated variable is of the class or Object type, its value change and value changes of all its attributes, that is, the attributes that **Object.keys(observedObject)** returns. Below is an example. 66 Declare the **ClassA** and **Model** classes. 67 68 ```ts 69 class ClassA { 70 public value: string; 71 72 constructor(value: string) { 73 this.value = value; 74 } 75 } 76 77 class Model { 78 public value: string; 79 public name: ClassA; 80 constructor(value: string, a: ClassA) { 81 this.value = value; 82 this.name = a; 83 } 84 } 85 ``` 86 87 Use \@State to decorate a variable of the Model class object type. 88 89 ```ts 90 // Class type 91 @State title: Model = new Model('Hello', new ClassA('World')); 92 ``` 93 94 Assign a value to the \@State decorated variable. 95 96 ```ts 97 // Assign a value to the class object. 98 this.title = new Model('Hi', new ClassA('ArkUI')); 99 ``` 100 101 Assign a value to an attribute of the \@State decorated variable. 102 103 ```ts 104 // Assign a value to an attribute of the class object. 105 this.title.value = 'Hi' 106 ``` 107 108 The value assignment of the nested attribute cannot be observed. 109 110 ```ts 111 // The value assignment of the nested attribute cannot be observed. 112 this.title.name.value = 'ArkUI' 113 ``` 114- When the decorated variable is of the array type, the addition, deletion, and updates of array items can be observed. Below is an example. 115 Declare the **ClassA** and **Model** classes. 116 117 ```ts 118 class Model { 119 public value: number; 120 constructor(value: number) { 121 this.value = value; 122 } 123 } 124 ``` 125 126 Use \@State to decorate a variable of the Model class array type. 127 128 ```ts 129 @State title: Model[] = [new Model(11), new Model(1)] 130 ``` 131 132 The value assignment of the array itself can be observed. 133 134 ```ts 135 this.title = [new Model(2)] 136 ``` 137 138 The value assignment of array items can be observed. 139 140 ```ts 141 this.title[0] = new Model(2) 142 ``` 143 144 The deletion of array items can be observed. 145 146 ```ts 147 this.title.pop() 148 ``` 149 150 The addition of array items can be observed. 151 152 ```ts 153 this.title.push(new Model(12)) 154 ``` 155 156 157### Framework Behavior 158 159- When a state variable is changed, the framework searches for components that depend on this state variable. 160 161- The framework executes an update method of the dependent components, which triggers re-rendering of the components. 162 163- Components or UI descriptions irrelevant to the state variable are not re-rendered, thereby implementing on-demand page updates. 164 165 166## Application Scenarios 167 168 169### Decorating Variables of Simple Types 170 171In this example, \@State is used to decorate the **count** variable of the simple type and turns it into a state variable. The change of **count** causes the update of the **\<Button>** component. 172 173- When the state variable **count** changes, the framework searches for components that depend on this state variable, which include only the **\<Button>** component in this example. 174 175- The framework executes the update method of the **\<Button>** component to implement on-demand update. 176 177 178```ts 179@Entry 180@Component 181struct MyComponent { 182 @State count: number = 0; 183 184 build() { 185 Button(`click times: ${this.count}`) 186 .onClick(() => { 187 this.count += 1; 188 }) 189 } 190} 191``` 192 193 194### Decorating Variables of the Class Object Type 195 196- In this example, \@State is used to decorate the variables **count** and **title** in the custom component **MyComponent**. The type of **title** is **Model**, a custom class. If the value of **count** or **title** changes, the framework searches for all **MyComponent** instances that depend on these variables and triggers re-rendering of them. 197 198- The **EntryComponent** has multiple **MyComponent** instances. The internal state change of the first **MyComponent** instance does not affect the second **MyComponent** instance. 199 200 201 202```ts 203class Model { 204 public value: string; 205 206 constructor(value: string) { 207 this.value = value; 208 } 209} 210 211@Entry 212@Component 213struct EntryComponent { 214 build() { 215 Column() { 216 // The parameters specified here will overwrite the default values defined locally during initial render. Not all parameters need to be initialized from the parent component. 217 MyComponent({ count: 1, increaseBy: 2 }) 218 MyComponent({ title: new Model('Hello, World 2'), count: 7 }) 219 } 220 } 221} 222 223@Component 224struct MyComponent { 225 @State title: Model = new Model('Hello World'); 226 @State count: number = 0; 227 private increaseBy: number = 1; 228 229 build() { 230 Column() { 231 Text(`${this.title.value}`) 232 Button(`Click to change title`).onClick(() => { 233 // The update of the @State decorated variable triggers the update of the <Text> component. 234 this.title.value = this.title.value === 'Hello ArkUI' ? 'Hello World' : 'HelloArkUI'; 235 }) 236 237 Button(`Click to increase count=${this.count}`).onClick(() => { 238 // The update of the @State decorated variable triggers the update of the <Button> component. 239 this.count += this.increaseBy; 240 }) 241 } 242 } 243} 244``` 245 246 247From this example, we learn the initialization process of an \@State decorated variable on initial render. 248 249 2501. Apply the locally defined default value. 251 252 ```ts 253 @State title: Model = new Model('Hello World'); 254 @State count: number = 0; 255 ``` 256 2572. Apply the named parameter value, if one is provided. 258 259 ```ts 260 MyComponent({ count: 1, increaseBy: 2 }) 261 ``` 262