文章

ArkTS 生命周期详解深度解析

ArkTS 组件与页面生命周期:aboutToAppear/aboutToDisappear 等回调时机。 讲清自定义组件与页面生命周期的差异,掌握后能答出「组件初始化与销毁时该做什么」。

ArkTS 生命周期详解深度解析

一句话概括

ArkTS 生命周期 = 页面级(aboutToAppear → onPageShow → onPageHide → aboutToDisappear)+ 组件级(aboutToAppear → build → aboutToDisappear),理解谁先谁后、谁重复调用,是杜绝资源泄漏和状态错乱的前提。

核心知识点

1. 页面生命周期——@Entry 组件专属

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Entry
@Component
struct HomePage {
  // ① 页面即将出现(只调一次)——初始化数据、注册监听
  aboutToAppear() {
    this.loadData();
    this.registerEventHub();
  }

  // ② 构建 UI(可能被多次调用——每次状态变化都 rebuild)
  build() {
    Column() {
      Text(`你好, ${this.username}`)
      ChildComponent()
    }
  }

  // ③ 页面显示(每次可见都触发)——恢复刷新、开启动画
  onPageShow() {
    this.startAutoRefresh();
  }

  // ④ 页面隐藏(被覆盖/切后台)——暂停刷新、释放临时资源
  onPageHide() {
    this.stopAutoRefresh();
  }

  // ⑤ 页面即将销毁(只调一次)——清理所有资源
  aboutToDisappear() {
    this.unregisterEventHub();
  }
}

2. 调用序:页面 A → 页面 B → 返回 A

1
2
3
4
5
6
7
// 导航到 B 页:
// A.onPageHide() → B.aboutToAppear() → B.build() → B.onPageShow()
//
// 从 B 返回 A:
// B.onPageHide() → A.onPageShow() → B.aboutToDisappear()
//
// 关键:A 的 aboutToAppear 只调一次,第二次回来只触发 onPageShow

3. 组件生命周期——@Component 专属

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component
struct ChildTimer {
  @State seconds: number = 0;
  private timerId?: number;

  // 只调一次——启定时器、初始化
  aboutToAppear() {
    this.timerId = setInterval(() => this.seconds++, 1000);
  }

  build() { Text(`运行: ${this.seconds}s`) }

  // 只调一次——清定时器,防止内存泄漏
  aboutToDisappear() {
    clearInterval(this.timerId);
  }
}
// 组件没有 onPageShow/onPageHide——那是页面级才有的

4. 父子组件的生命周期顺序

1
2
3
4
5
6
7
8
9
10
// 页面首次渲染:
// 父.aboutToAppear()
//   子1.aboutToAppear() → 子1.build()
//   子2.aboutToAppear() → 子2.build()
// 父.build()
// 父.onPageShow()

// 状态变化导致父 rebuild:
// 父.build() → 子1.build() → 子2.build()
// 注意:aboutToAppear 不会再调!

5. 资源管理黄金法则

1
2
3
4
5
6
7
8
9
10
// 配对原则:
// aboutToAppear   ←→  aboutToDisappear
// onPageShow      ←→  onPageHide
// subscribe       ←→  unsubscribe
// open            ←→  close
// setInterval     ←→  clearInterval

// ❌ 常见泄漏:
aboutToAppear() { window.addEventListener('resize', handler); }
// 忘了在 aboutToDisappear 里 removeEventListener → 内存泄漏!

其实你每天都在用

  • 数据加载时机:aboutToAppear 里发网络请求 → 组件出现时数据已就绪
  • 定时刷新:onPageShow 启动轮询、onPageHide 停止 → 不浪费后台流量
  • 事件监听:aboutToAppear 注册 EventHub、aboutToDisappear 注销 → 不泄漏
  • 输入框聚焦:onPageShow 时 autofocus、onPageHide 时收起键盘
  • 动画控制:onPageShow 启动入场动画、onPageHide 保存动画状态

常见误解(FAQ)

  • ❌ 误区:「aboutToAppear 每次显示页面都会调用」 只调一次。页面被覆盖后回来只调 onPageShow,不会重新 aboutToAppear。如果每次回来都要重新请求数据,写在 onPageShow 里。

  • ❌ 误区:「build() 只会在初始化时调用」 build 是”每次状态变化”都可能被调用的。你改了 @State 变量,build 就重新执行——但不是重建所有组件,框架会 diff 只更新变了的部分。

  • ❌ 误区:「子组件的 aboutToDisappear 在父的被调用之前」 不是固定的。如果子组件是通过 if/else 条件渲染的,条件从 true 变 false 时,子的 aboutToDisappear 会在父的 rebuild 过程中调用。销毁顺序是”先子后父”。

  • ❌ 误区:「在 aboutToDisappear 里调 setState 没问题」 组件已标记销毁,再 setState 无意义且可能报错。aboutToDisappear 的职责是清理,不是更新 UI。

一句话总结

生命周期管理的核心就是”配对”——哪里创建、哪里销毁,哪里订阅、哪里取消,凡是没有配对的资源操作都是定时炸弹。

本文由作者按照 CC BY 4.0 进行授权