1# Attribute Updater (AttributeUpdater)
2
3## Overview
4
5When dealing with frequent updates to a large number of attributes, using state variables can lead to significant computational overhead in frontend state management. This is because it requires full updates of all attributes for individual components. Although the [AttributeModifier](../reference/apis-arkui/arkui-ts/ts-universal-attributes-attribute-modifier.md) mechanism allows for selective updates based on specific needs, the frontend still applies some default strategies for differentiation (diffing) and resetting attributes.
6
7This is where **AttributeUpdater** comes into the picture. As a special type of **AttributeModifier**, **AttributeUpdater** not only inherits all the functionality of **AttributeModifier** but also extends its capabilities by allowing access to the attribute object. By using the attribute object, you can update specific attributes without relying on state variables. With **AttributeUpdater**, you can implement custom update strategies, further improving the performance of attribute updates.
8
9This flexibility, however, comes with a trade-off: It does not enforce the "single source of truth" rule, which means that there is a risk of conflicts when the same attributes are updated through both **AttributeUpdater** and state variables. To avoid such conflicts, you need to ensure that attribute settings are applied logically and consistently.
10
11## API Definition
12
13```ts
14export declare class AttributeUpdater<T, C = Initializer<T>> implements AttributeModifier<T> {
15
16  applyNormalAttribute?(instance: T): void;
17
18  initializeModifier(instance: T): void;
19
20  get attribute(): T | undefined;
21
22  updateConstructorParams: C;
23}
24```
25
26**AttributeUpdater** enhances the **AttributeModifier** API by offering additional features. It provides **initializeModifier** for initializing a component's attributes, **attribute** for obtaining the attribute object (which enables direct updates to the component's attributes), and **updateConstructorParams** for directly updating the component's constructor parameters.
27
28## How to Use
29
30- You can extend the **AttributeUpdater\<T>** class and set it up through the universal method **AttributeModifier** of the component. When the binding is first established, the **initializeModifier** API is triggered to initialize attributes. This is followed by a series of lifecycle events that are consistent with those of **AttributeModifier**.
31- After the component is initialized, you can obtain the attribute object through the **attribute** method of the **AttributeUpdater** instance. If the component is not initialized, the method will return **undefined**.
32- Modifying attributes through **attribute** will store the latest settings within the current object and immediately trigger an update of the component's attributes.
33- Designating an **AttributeUpdater** instance as a mutable state variable, or updating the attributes of the corresponding component through other state variables, will trigger **applyNormalAttribute**. If you do not override this logic, by default, all attributes obtained by the **attribute** object will be updated in batch.
34- If you override the **applyNormalAttribute** API without calling **super**, you will not be able to obtain the attribute object, and the **initializeModifier** method will not be executed.
35- A single **AttributeUpdater** object can be associated with only one component. If it is associated with multiple components, attribute settings will be applied to only one of these components.
36
37## Directly Modifying Attributes Through Modifier
38
39After a component is initialized, you can use the **attribute** method of the **AttributeUpdater** instance to obtain the attribute object. Modifying attributes directly through this object will immediately trigger an update to the component's attributes.
40
41```ts
42import { AttributeUpdater } from '@ohos.arkui.modifier'
43
44class MyButtonModifier extends AttributeUpdater<ButtonAttribute> {
45  // The initializeModifier method is triggered upon the first binding, initializing the attributes.
46  initializeModifier(instance: ButtonAttribute): void {
47    instance.backgroundColor('#2787D9')
48      .width('50%')
49      .height(30)
50  }
51}
52
53@Entry
54@Component
55struct updaterDemo {
56  modifier: MyButtonModifier = new MyButtonModifier()
57
58  build() {
59    Row() {
60      Column() {
61        Button("Button")
62          .attributeModifier(this.modifier)
63          .onClick(() => {
64            // Directly modify the component's attributes through attribute, which will trigger an immediate update.
65            this.modifier.attribute?.backgroundColor('#17A98D').width('30%')
66          })
67      }
68      .width('100%')
69    }
70    .height('100%')
71  }
72}
73```
74![AttributeUpdater](figures/AttributeUpdater.gif)
75
76
77## Updating Component Constructor Parameters Through Modifier
78
79You can directly update the constructor parameters of a component using the **updateConstructorParams** method of an **AttributeUpdater** instance.
80
81```ts
82import { AttributeUpdater } from '@ohos.arkui.modifier'
83
84class MyTextModifier extends AttributeUpdater<TextAttribute, TextInterface> {
85  initializeModifier(instance: TextAttribute): void {
86  }
87}
88
89@Entry
90@Component
91struct updaterDemo {
92  modifier: MyTextModifier = new MyTextModifier()
93
94  build() {
95    Row() {
96      Column() {
97        Text("Text")
98          .attributeModifier(this.modifier)
99          .fontColor(Color.White)
100          .fontSize(14)
101          .border({ width: 1 })
102          .textAlign(TextAlign.Center)
103          .lineHeight(20)
104          .width(200)
105          .height(50)
106          .backgroundColor('#2787D9')
107          .onClick(() => {
108            // Call the updateConstructorParams method to directly update the component's constructor parameters.
109            this.modifier.updateConstructorParams('Update');
110          })
111      }
112      .width('100%')
113    }
114    .height('100%')
115  }
116}
117```
118![AttributeUpdater](figures/AttributeUpdater2.gif)
119