<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: xiaoyao-yao</title>
    <description>The latest articles on DEV Community by xiaoyao-yao (@xiaoyaoyao).</description>
    <link>https://dev.to/xiaoyaoyao</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3298986%2F83794f8b-16c3-4b85-bbd8-a7f985fa18b1.png</url>
      <title>DEV Community: xiaoyao-yao</title>
      <link>https://dev.to/xiaoyaoyao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xiaoyaoyao"/>
    <language>en</language>
    <item>
      <title>After obtaining the NEXT-Data data from the AppStore, the HarmonyOS NEXT-Data data is found to be the same data</title>
      <dc:creator>xiaoyao-yao</dc:creator>
      <pubDate>Fri, 27 Jun 2025 05:23:11 +0000</pubDate>
      <link>https://dev.to/xiaoyaoyao/hong-meng-next-datalei-xing-shu-ju-tong-guo-appstorehuo-qu-hou-zhao-yuan-ben-yang-de-shu-ju-zhi-yang-dan-shi-bi-jiao-jie-guo-que-wei-false-492e</link>
      <guid>https://dev.to/xiaoyaoyao/hong-meng-next-datalei-xing-shu-ju-tong-guo-appstorehuo-qu-hou-zhao-yuan-ben-yang-de-shu-ju-zhi-yang-dan-shi-bi-jiao-jie-guo-que-wei-false-492e</guid>
      <description>&lt;p&gt;​&lt;br&gt;
I'm using&lt;/p&gt;

&lt;p&gt;dataTime.indexOf(Time)&lt;br&gt;
to find the same data in the Date[] array,&lt;br&gt;
I found that even though I know exactly that there is a value of the Data property in the dataTiem that is the same as the Time,&lt;br&gt;
However, it gets -1 and the comparison is false.&lt;/p&gt;

&lt;p&gt;Analyze the cause of the error:&lt;/p&gt;

&lt;p&gt;Reference Comparison Mechanism Date is a complex data type (object) that compares the memory address of the object rather than the actual value when compared directly in JavaScript/ArkTS using === or indexOf. For example, even if the Timestamp of the Date object obtained from AppStorage is the same as that of the original object, it may be a different instance, resulting in indexOf returning -1. In the vernacular, it is a complex data type of Date[], when comparing, it will compare whether their addresses are the same, but will not compare their values, which is essentially caused by the difference between object reference comparison and value comparison, so how do we achieve it? Compare their values to get the results we expect.&lt;/p&gt;

&lt;p&gt;The sample code is as follows:&lt;/p&gt;

&lt;p&gt;Method 1: Use JSON&lt;/p&gt;

&lt;p&gt;@Entry&lt;br&gt;
@Component&lt;br&gt;
struct Index {&lt;br&gt;
  @State dataTime: Array = []&lt;br&gt;
  @State Time: Date = new Date()&lt;br&gt;
  aboutToAppear(): void {&lt;br&gt;
    this.dataTime.forEach((item)=&amp;gt;{&lt;br&gt;
      console.log(''+Boolean(JSON.stringify(item)===JSON.stringify(this.Time)))&lt;br&gt;
    })&lt;br&gt;
  }&lt;br&gt;
  build() {&lt;/p&gt;

&lt;p&gt;}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Use JSON.stringify() to compare Date objects, i.e. serialized strings&lt;/p&gt;

&lt;p&gt;Method 2: Use the original method to compare, that is, use getTime() to compare timestamps&lt;/p&gt;

&lt;p&gt;@Entry&lt;br&gt;
@Component&lt;br&gt;
struct Index {&lt;br&gt;
  @State dataTime: Array = []&lt;br&gt;
  @State Time: Date = new Date()&lt;br&gt;
  aboutToAppear(): void {&lt;br&gt;
    this.dataTime.forEach((item)=&amp;gt;{&lt;br&gt;
      console.log(Boolean(item.getTime()=== this.Time.getTime())+'')&lt;br&gt;
    })&lt;br&gt;
  }&lt;br&gt;
  build() {&lt;/p&gt;

&lt;p&gt;}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Compare timestamps (numeric types) directly to avoid referencing issues. Efficient performance without the need to convert data types. &lt;/p&gt;

&lt;p&gt;Method 3: Storage optimization&lt;/p&gt;

&lt;p&gt;When persisting the Date type, the timestamp (number) is stored instead of the Date object.&lt;/p&gt;

&lt;p&gt;Save to AppStorage&lt;br&gt;
AppStorage.setOrCreate('lastLogin', new Date().getTime());&lt;/p&gt;

&lt;p&gt;Read and convert to Date&lt;br&gt;
const timestamp = AppStorage.get('lastLogin');&lt;br&gt;
const lastLogin = new Date(timestamp);&lt;/p&gt;

&lt;p&gt; Note that this only applies to simple Date objects, and may not be valid if the object contains other attributes. Performance is low, and frequent operations may affect rendering.&lt;/p&gt;

&lt;p&gt;You can choose the right way according to your needs.&lt;/p&gt;

&lt;p&gt;​&lt;/p&gt;

</description>
    </item>
    <item>
      <title>HarmonyOS NEXT-HMRouter, the problem cannot be jumped after using router</title>
      <dc:creator>xiaoyao-yao</dc:creator>
      <pubDate>Fri, 27 Jun 2025 05:22:30 +0000</pubDate>
      <link>https://dev.to/xiaoyaoyao/hong-meng-next-hmrouterzai-shi-yong-routerhou-wu-fa-tiao-zhuan-wen-ti-jie-jue-25oh</link>
      <guid>https://dev.to/xiaoyaoyao/hong-meng-next-hmrouterzai-shi-yong-routerhou-wu-fa-tiao-zhuan-wen-ti-jie-jue-25oh</guid>
      <description>&lt;p&gt;​&lt;br&gt;
The author uses a third-party library @HMRouter to build a three-layer architecture (basic feature layer, product customization layer, and public capability layer) of HarmonyOS to complete the App, and when the cross-package jump is made, a strange bug is encountered when the login page enters the home page, after we use router.push() to jump, and then use HMRouter to jump to the page suddenly, so what should we do? , and now share the solution to the bug.&lt;/p&gt;

&lt;p&gt;The sample error code looks like this:&lt;/p&gt;

&lt;p&gt;import { router } from '&lt;a class="mentioned-user" href="https://dev.to/kit"&gt;@kit&lt;/a&gt;.ArkUI';&lt;/p&gt;

&lt;p&gt;@Entry&lt;br&gt;
@ComponentV2&lt;br&gt;
struct LoginPage {&lt;br&gt;
  @State message: string = 'Hello World';&lt;br&gt;
  aboutToAppear(): void {&lt;br&gt;
    console.log('LifeCircle creation')&lt;br&gt;
  }&lt;br&gt;
  onDidBuild(): void {&lt;br&gt;
    console.log('The LifeCircle component is built')&lt;br&gt;
  }&lt;br&gt;
  onPageShow(): void {&lt;br&gt;
    console.log('PageShow')&lt;br&gt;
  }&lt;br&gt;
  onPageHide(): void {&lt;br&gt;
    console.log('Page - Page hidden')&lt;br&gt;
  }&lt;br&gt;
  build() {&lt;br&gt;
    Column(){&lt;br&gt;
        /&lt;em&gt;The login page code is omitted&lt;/em&gt;&lt;em&gt;/&lt;br&gt;
    }&lt;br&gt;
    .onVisibleAreaChange([1.0],()=&amp;gt;{&lt;br&gt;
        /&lt;/em&gt;&lt;em&gt;Omit the login verification process&lt;/em&gt;*/&lt;br&gt;
      router.replaceUrl({url:'pages/Index'})&lt;br&gt;
    })&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;For the sake of convenience, when the author has logged in, he directly logged in to onVisibleAreaChange and jumped to the home page, and found that he couldn't jump to other pages using HMRouter, and there was no response when he clicked the jump button.&lt;/p&gt;

&lt;p&gt;Analyze the cause of the error:&lt;/p&gt;

&lt;p&gt;onVisibleAreaChange is a high-frequency triggered callback, if you jump directly here, the route status may be abnormal because the page is not fully initialized. (Page Lifecycle Conflict)&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;Avoid jumping directly in onVisibleAreaChange and instead use explicit triggers (such as button clicks) or page lifecycle callbacks&lt;/p&gt;

&lt;p&gt;For example, the following example code shows:&lt;/p&gt;

&lt;p&gt;import { router } from '&lt;a class="mentioned-user" href="https://dev.to/kit"&gt;@kit&lt;/a&gt;.ArkUI';&lt;/p&gt;

&lt;p&gt;@Entry&lt;br&gt;
@Component&lt;br&gt;
struct LoginPage{&lt;br&gt;
  @State message: string = 'Hello World';&lt;br&gt;
  aboutToAppear(): void {&lt;br&gt;
    router.replaceUrl({url:'pages/Index'})&lt;br&gt;
    console.log('LifeCircle creation')&lt;br&gt;
  }&lt;br&gt;
  onDidBuild(): void {&lt;br&gt;
    console.log('The LifeCircle component is built')&lt;br&gt;
  }&lt;br&gt;
  onPageShow(): void {&lt;br&gt;
    console.log('PageShow')&lt;br&gt;
  }&lt;br&gt;
  onPageHide(): void {&lt;br&gt;
    console.log('Page - Page hidden')&lt;br&gt;
  }&lt;br&gt;
  build() {&lt;br&gt;
    Column(){&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;In aboutToAppear, just redirect to our page.&lt;/p&gt;

&lt;p&gt;Actual result: After jumping to the homepage in the page lifecycle callback, HMRouter can jump to the page normally. The bug was successfully fixed.&lt;br&gt;
​&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Harmony NEXT-Difference between State Management V1 and State Management V2</title>
      <dc:creator>xiaoyao-yao</dc:creator>
      <pubDate>Fri, 27 Jun 2025 05:16:18 +0000</pubDate>
      <link>https://dev.to/xiaoyaoyao/hong-meng-next-zhuang-tai-guan-li-v1he-zhuang-tai-guan-li-v2de-chai-bie-4g97</link>
      <guid>https://dev.to/xiaoyaoyao/hong-meng-next-zhuang-tai-guan-li-v1he-zhuang-tai-guan-li-v2de-chai-bie-4g97</guid>
      <description>&lt;p&gt;​&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In V2, there is no &lt;a class="mentioned-user" href="https://dev.to/link"&gt;@link&lt;/a&gt; to bind parent and child components in both directions.
Therefore, we need to @Event the events of the parent component in the child component to implement the decoration callback (in the vernacular: the child component calls the function of the @Event decoration, passes in the parameters, and modifies the parameters in the parent component). In the parent component, pass in the function to the child component, note that we need to use the arrow function to wrap the function we write to the event, to ensure that the this of the event we pass in is not empty.
@Event can only be used in components that @ComponentV2 decoration
Sample code:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;@Entry&lt;br&gt;
@ComponentV2&lt;br&gt;
struct Index {&lt;br&gt;
  &lt;a class="mentioned-user" href="https://dev.to/local"&gt;@local&lt;/a&gt; title: string = "To be modified";&lt;/p&gt;

&lt;p&gt;build() {&lt;br&gt;
    Column() {&lt;br&gt;
      Child({&lt;br&gt;
        changeFactory: () =&amp;gt; {&lt;br&gt;
         this.title="Revised"&lt;br&gt;
        }&lt;br&gt;
      })&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;@ComponentV2&lt;br&gt;
struct Child {&lt;br&gt;
  @Event changeFactory: () =&amp;gt; void = () =&amp;gt; {};&lt;br&gt;
  build() {&lt;br&gt;
    Column() {&lt;br&gt;
      Button("Change the title")&lt;br&gt;
        .onClick(() =&amp;gt; {&lt;br&gt;
          this.changeFactory();&lt;br&gt;
        })&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The @State in V1 has been transformed into &lt;a class="mentioned-user" href="https://dev.to/local"&gt;@local&lt;/a&gt;
@State decorator is not aware of initialization from the outside
The name has changed, but the writing is still the same, but &lt;a class="mentioned-user" href="https://dev.to/local"&gt;@local&lt;/a&gt; cannot be mixed with the @Observed decorated class instance object. Everything else is the same: For example, when decorating simple type arrays and value types, you can observe changes in the array as a whole or in the array items and changes in the value type.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;3.@Watch is @Monitor in V2&lt;br&gt;
In V1@Watch you can only listen to the changes in the first layer of attributes, while in V2, you can @Monitor and modify, and use &lt;a class="mentioned-user" href="https://dev.to/trace"&gt;@trace&lt;/a&gt; in the corresponding deep variables.&lt;br&gt;
Simple implementation of the sample code:&lt;/p&gt;

&lt;p&gt;@Entry&lt;br&gt;
@ComponentV2&lt;br&gt;
struct monitorExample {&lt;br&gt;
  &lt;a class="mentioned-user" href="https://dev.to/local"&gt;@local&lt;/a&gt; apple: number = 0;&lt;br&gt;
  @Monitor('apple')&lt;br&gt;
  onFruitChange(monitor: IMonitor) {&lt;br&gt;
    console.log(&lt;code&gt;apple changed from ${monitor.value()?.before} to ${monitor.value()?.now}&lt;/code&gt;);&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;build() {&lt;br&gt;
    Column(){&lt;br&gt;
      Text(&lt;code&gt;apple count: ${this.apple}&lt;/code&gt;)&lt;br&gt;
      Button("add apple")&lt;br&gt;
        .onClick(()=&amp;gt; {&lt;br&gt;
          this.apple++;&lt;br&gt;
        })&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Extend:&lt;/p&gt;

&lt;p&gt;V1: Relies on decorator chains (such as @State @ObjectLink) to implement one-way data flow, and only supports the observation of the first-layer properties of objects. Nested objects need to encapsulate components layer by layer, and the code is redundant.&lt;br&gt;&lt;br&gt;
V2: Implements deep attribute monitoring through @ObservedV2 &lt;a class="mentioned-user" href="https://dev.to/trace"&gt;@trace&lt;/a&gt;, and supports attribute change detection (such as obj.a.b.c) of nested objects at any level, without the need for additional component encapsulation &lt;/p&gt;

&lt;p&gt;​&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
