HarmonyOS에서 @Track 데코레이터를 활용한 상태 관리

개요

@Track은 클래스 객체의 속성 데코레이터입니다. 상태 변수인 클래스 객체에서 @Track으로 데코레이트된 속성이 변경되면, 해당 속성과 연결된 UI만 업데이트됩니다. 데코레이트되지 않은 속성은 UI에서 사용할 수 없습니다. API 버전 11부터 ArkTS 카드에서 사용이 지원됩니다.

데코레이터 설명

  • 데코레이터 매개변수: 없음
  • 적용 가능 변수: 클래스 객체의 비정적 멤버 속성

변화 관찰 및 동작

클래스 객체가 상태 변수일 때 @Track으로 데코레이트된 속성이 변경되면 관련 UI가 업데이트됩니다. 클래스에 @Track이 적용된 속성이 없으면 기존 동작이 유지됩니다. @Track은 깊은 관찰(deep observation)을 지원하지 않아 불필요한 리렌더링을 방지합니다.

예제

class TrackedLogger {
  @Track msg1: string;
  @Track msg2: string;
  
  constructor(text: string) {
    this.msg1 = text;
    this.msg2 = 'Earth';
  }
}

class BasicLogger {
  msg1: string;
  msg2: string;
  
  constructor(text: string) {
    this.msg1 = text;
    this.msg2 = 'Planet';
  }
}

@Entry
@Component
struct LoggerComponent {
  @State tracked: TrackedLogger = new TrackedLogger('Hello');
  @State basic: BasicLogger = new BasicLogger('Hi');
  
  logRender(index: number) {
    console.log(`텍스트 ${index} 렌더링됨`);
    return 50;
  }

  build() {
    Column() {
      Text(this.tracked.msg1) // UI노드1
        .fontSize(this.logRender(1))
      Text(this.tracked.msg2) // UI노드2
        .fontSize(this.logRender(2))
      
      Button('추적 메시지1 변경')
        .onClick(() => {
          this.tracked.msg1 = 'Bye';
        })
      
      Text(this.basic.msg1) // UI노드3
        .fontSize(this.logRender(3))
      Text(this.basic.msg2) // UI노드4
        .fontSize(this.logRender(4))
      
      Button('기본 메시지1 변경')
        .onClick(() => {
          this.basic.msg1 = 'See you';
        })
    }
    .width('100%')
    .height('100%')
  }
}

동작 분석:

  • TrackedLogger의 속성은 모두 @Track으로 데코레이트됨: "추적 메시지1 변경" 버튼 클릭 시 UI노드1만 업데이트
  • BasicLogger에는 @Track 적용 안 됨: "기본 메시지1 변경" 버튼 클릭 시 UI노드3과 4 모두 업데이트

제한 사항

  1. 비@Track 속성은 UI에서 사용 불가(컴포넌트 바인딩, 하위 컴포넌트 초기화). 잘못 사용 시 JSCrash 발생. 이벤트 콜백이나 생명주기 함수 등 비UI 영역에서는 사용 가능
  2. @Track 적용 클래스와 미적용 클래스 혼합 사용 권장하지 않음(유니온 타입, 클래스 상속 등)

사용 시나리오

@Track과 컴포넌트 업데이트

class AppLog {
  @Track content: string;
  appOwner: string;
  logId: number;
  timestamp: Date;
  region: string;
  cause: string;

  constructor(info: string) {
    this.content = info;
    this.appOwner = 'OH';
    this.logId = 0;
    this.timestamp = new Date();
    this.region = 'KR';
    this.cause = 'None';
  }
}

@Entry
@Component
struct LogViewer {
  @State logEntry: AppLog = new AppLog('초기 정보');

  build() {
    Column() {
      Text(this.logEntry.content)
        .fontSize(50)
        .onClick(() => {
          console.log(`소유자: ${this.logEntry.appOwner}
                      ID: ${this.logEntry.logId}
                      시간: ${this.logEntry.timestamp}
                      지역: ${this.logEntry.region}
                      사유: ${this.logEntry.cause}`);
          
          this.logEntry.timestamp = new Date();
          this.logEntry.logId++;
          this.logEntry.content += ' 추가정보';
        })
    }
    .width('100%')
    .height('100%')
  }
}

업데이트 절차:

  1. Text.onClick 이벤트에서 content 문자열에 '추가정보' 연계
  2. @State logEntry 변수의 @Track 속성(content) 변경으로 Text 컴포넌트 재렌더링

태그: HarmonyOS ArkTS 데코레이터 상태관리 UI성능

6월 30일 19:40에 게시됨