ArkTS 进阶之道12if/条件渲染边界——为啥 build 里不能写 if 语句本文是「ArkTS 进阶之道」系列第 12 篇续「ArkUI 渎染哲学」阶段。上篇讲 build() 重渲边界篇 60——State 参只刷依赖 UI 不刷全 build。本文讲条件渲染边界build 里 if 语句报错 vs if(…){} 条件渲染装饰器合法——根因在 build 是装饰器渲染树不是语句执行流if 贬饰器编译期绑渲染树分支不是运行时语句跳转。能力系列篇 17 讲过条件渲染怎么用本文讲为哈 if 语句报错 if 贬饰器合法——根因在渲染树绑定不是语句执行。一、开篇build 里 if 不是语句是装饰器绑渲染树分支不是执行跳转你写 TypeScript/React 时条件渲染是「魔法」JSX 里 if 语句不能直接写要用三元表达式//子组件// React JSX 里 if 语句不能直接写 function Component() { const show true return ( View {/* if (show) { Textxxx/Text } ← JSX 里 if 语句不能直接写报错 */} {show ? Text显示/Text : null} ← 要用三元表达式魔法 {show Text显示/Text} ← 或用 短路魔法 /View ) } // JSX 里 if 语句不能直接写要用三元/ 魔法绕你写鸿蒙 ArkTS 时build 里if 贬饰器直接写——不用三元/ 绕// ArkTS build 里 if 贬饰器直接写 Entry Component struct Index { State show: boolean true build() { Column() { if (this.show) { ← if 贬饰器直接写合法不是 if 语句 Text(显示) ← showtrue 显示这分支 } else { Text(隐藏) ← showfalse 显示这分支 } } } } // build 里 if 贬饰器直接写合法不用三元/ 绕不是 if 语句魔法 vs 贬饰器的区别React JSX 把条件渲染当「魔法」if 语句不能写三元/ 绕ArkTS 把 if 当「条件渲染装饰器」build 里 if 直接写编译期绑渲染树分支。根因不是魔法是渲染树绑定——build 里 if 不是运行时语句跳转是编译期绑渲染树分支的装饰器。二、根因build 里 if 贬饰器的渲染树分支绑定机制鸿蒙 ArkUI 的 build 里 if 是渲染树分支绑定——编译期把 if/else 分支绑成渲染树分支运行时按状态选分支渲染不是运行时语句跳转来自三重绑定机制。机制 1if 贬饰器编译期绑渲染树分支——不是运行时语句if 贬饰器编译期绑渲染树分支——把 if/else 分支编成渲染树的两个分支不是运行时执行的语句Entry Component struct Index { State show: boolean true build() { Column() { if (this.show) { ← if 贬饰器编译期绑渲染树分支1 Text(显示) ← 分支1绑这个 Text } else { ← else 贬饰器编译期绑渲染树分支2 Text(隐藏) ← 分支2绑这个 Text } } } } // 编译期if 绑渲染树分支1Text显示 else 绑渲染树分支2Text隐藏) // 运行时按 show 值选分支1或分支2渲染不是运行时 if 语句跳转编译期绑渲染树分支if 贬饰器编译期把 if 分支绑成渲染树分支1Text’显示’else 贬饰器绑成渲染树分支2Text’隐藏’。运行时按show值选分支1或分支2渲染——不是运行时 if 语句跳转是编译期绑的渲染树分支按状态选。根因不是语句是渲染树分支绑定。机制 2运行时按状态选分支渲染——不是运行时 if 语句跳转if 贬饰器运行时按状态选分支渲染——状态变触发重选分支重渲不是运行时 if 语句跳转执行Entry Component struct Index { State show: boolean true build() { Column() { if (this.show) { Text(显示) ← showtrue 选这分支渲染 } else { Text(隐藏) ← showfalse 选这分支渲染 } Button(切 show) .onClick(() { this.show !this.show }) ← show 反 选分支重渲 } } } // showtrue 选分支1Text显示showfalse 选分支2Text隐藏 // show 反 重选分支重渲不是运行时 if 语句跳转是渲染树分支重选运行时选分支渲染if 贬饰器运行时按show值选分支渲染——showtrue 选分支1Text’显示’showfalse 选分支2Text’隐藏’。状态变触发重选分支重渲——不是运行时 if 语句跳转执行是渲染树分支按状态重选。根因不是语句跳转是渲染树分支重选。机制 3if 语句报错边界——build 不是语句执行流是渲染树build 里 if语句报错——build 是渲染树不是语句执行流if 语句是运行时跳转跟渲染树绑定冲突Entry Component struct Index { State show: boolean true build() { Column() { // ❌ if 语句报错build 不是语句执行流 // if (this.show) { Text(显示) } ← 这是 if 语句不是装饰器报错 // ✅ if 贬饰器合法build 是渲染树if 绑分支 if (this.show) { Text(显示) ← if 贬饰器绑渲染树分支合法 } } } } // if 语句报错根因build 是渲染树不是语句执行流if 语句运行时跳转跟渲染树绑定冲突 // if 贬饰器合法根因if 编译期绑渲染树分支运行时按状态选分支渲染if 语句报错边界build 里 if 语句报错根因是 build 是渲染树不是语句执行流——if 语句是运行时跳转执行跟渲染树编译期绑定冲突报错。if 贬饰器合法根因是 if 编译期绑渲染树分支运行时按状态选分支渲染不冲突。根因不是语法区别是渲染树绑定 vs 语句执行流的边界冲突。三、真机配图if 语句报错 vs if 条件渲染装饰器对比证据初始态showtrue 显 if 分支、count0 显 else 分支均条件渲染边界初始值点调两按钮后showfalse 切到 else 分支显示、count1 切到 count0 分支显示均条件渲染边界对比证据齐对比证据点改 show 按钮后切到 else 分支显示showfalse 显「else 分支」点改 count 按钮后切到 count0 分支显示count1 显「count0 显示」。if 不是语句是装饰器绑渲染树分支——if 贬饰器编译期绑渲染树分支1/分支2运行时按状态选分支渲染不是运行时 if 语句跳转。if 语句报错根因是 build 是渲染树不是语句执行流if 语句运行时跳转跟渲染树绑定冲突。四、真解法if 条件渲染的三个场景场景 1if/else 二分支渲染90% 场景首选状态切分支Entry Component struct Index { State show: boolean true build() { Column() { if (this.show) { Text(显示) ← showtrue 反这分支 } else { Text(隐藏) ← showfalse 反这分支 } Button(切) .onClick(() { this.show !this.show }) ← 反切分支 } } }为哈能跑if/else 二分支渲染——if 绑分支1else 绑分支2状态变切分支重渲。首选这个90% 的场景状态切两分支用 if/else 就够。要写「状态切两分支渲染」时用这个——不用三元/ 绕if 贬饰器直接绑两分支按状态切。场景 2if 多条件分支渲染if/else if/else 多分支Entry Component struct Index { State level: number 0 // 0低 1中 2高 build() { Column() { if (this.level 0) { Text(低) ← level0 反这分支 } else if (this.level 1) { Text(中) ← level1 反这分支 } else { Text(高) ← level2 反这分支 } Button(升级) .onClick(() { this.level (this.level 1) % 3 }) ← 反切分支 } } }为哈能跑if/else if/else 多分支渲染——level0 显「低」level1 显「中」level2 显「高」。要写「状态切多分支渲染」时用这个——if/else if/else 贬饰器绑多分支按状态选不用 switch/三元嵌套。场景 3if 嵌套条件渲染if 里嵌 if多状态组合条件Entry Component struct Index { State isAdmin: boolean true State isLoggedIn: boolean true build() { Column() { if (this.isLoggedIn) { if (this.isAdmin) { Text(管理员面板) ← 已登录管理员 显这 } else { Text(用户面板) ← 已登录普通用户 显这 } } else { Text(登录页) ← 未登录 显这 } Button(切登录) .onClick(() { this.isLoggedIn !this.isLoggedIn }) Button(切管理员) .onClick(() { this.isAdmin !this.isAdmin }) } } }为哈能跑if 嵌套条件渲染——isLoggedInisAdmin 两状态组合条件选分支。要写「多状态组合条件渲染」时用这个——if 嵌套 if 绑嵌套渲染树分支多状态组合选分支渲染不用三元嵌套/ 组合。五、一句话哲学build 里 if 不是语句是装饰器绑渲染树分支不是执行跳转。ArkUI 的 build 里 if 贬饰器编译期绑渲染树分支if 绑分支1/else 绑分支2运行时按状态选分支渲染不是运行时 if 语句跳转。根因不是语法区别是渲染树绑定 vs 语句执行流的边界——if 贬饰器编译期绑渲染树分支合法 运行时按状态选分支渲染不是语句跳转 if 语句报错边界build 是渲染树不是语句执行流。对比 React JSX if 语句不能写要三元/ 绕ArkTS if 贬饰器直接绑分支。渲染哲学阶段串讲build() 重渲边界篇 60State 参只刷依赖 UI 不刷全 build→ if 条件渲染边界篇 61if 贬饰器绑渲染树分支不是 if 语句——两篇讲清 ArkUI 渎染哲学渲染树绑定build 编译期记依赖/if 绑分支根因都是编译期绑渲染树不是运行时语句执行。下一篇ArkTS 进阶之道13—— ForEach 循环渲染边界为啥 build 里不能写 for 循环对应能力系列篇 18讲根因——续「ArkUI 渎染哲学」阶段收尾。能力系列回链能力系列篇本文进阶点篇 17 条件渲染用法if 条件渲染边界根因if 贬饰器绑渲染树分支篇 18 循环渲染用法下篇预告ForEach 循环渲染边界根因篇 13 State 基础用法状态哲学State 赋值就刷 UI 依赖追踪真机 demo 完整代码// 篇 61 demoif 语句报错 vs if 条件渲染装饰器对比 // 对比build 里 if 语句报错 vs if(...){} 条件渲染合法 Entry Component struct Index { State count: number 0 State show: boolean true State log: string (未操作) build() { Column({ space: 12 }) { Text(篇 61 配图if 语句报错 vs if 条件渲染装饰器对比) .fontSize(18).fontWeight(FontWeight.Bold).margin({ top: 20, bottom: 8 }) Text(build 里 if 语句报错 vs if(...){} 条件渲染合法对比证据) .fontSize(12).fontColor(#888).margin({ bottom: 16 }) Column({ space: 6 }) { Text(count ${this.count}).fontSize(15).fontWeight(FontWeight.Bold) Text(show ${this.show}).fontSize(15).fontWeight(FontWeight.Bold) Text(日志${this.log}).fontSize(12).fontColor(#333).margin({ top: 4 }) } .width(92%).padding(12).backgroundColor(#f5f5f5).borderRadius(8) // ✅ if 条件渲染装饰器合法不是 if 语句 if (this.show) { Text(✅ if 条件渲染装饰器合法showtrue 显示).fontSize(14).fontColor(#2563eb) } else { Text(✅ else 分支showfalse 显示).fontSize(14).fontColor(#dc2626) } // ✅ if 条件渲染装饰器 依赖状态 if (this.count 0) { Text(✅ count0 显示count${this.count}).fontSize(14).fontColor(#2563eb) } else { Text(✅ count0 显示还没点).fontSize(14).fontColor(#dc2626) } // ❌ build 里 if 语句报错对比证据注释掉避编译炸 // if (this.show) { Text(xxx) } ← 这是语句不是装饰器编译报错 Button(改 State show切条件渲染分支) .width(92%).height(44).fontSize(14) .onClick(() { this.show !this.show // ✅ 改 show 切 if 条件渲染分支 this.log 改 show${this.show}if 条件渲染切分支不是 if 语句 }) Button(改 State count切 count0 条件渲染) .width(92%).height(44).fontSize(14) .onClick(() { this.count // ✅ 改 count 切 if count0 条件渲染 this.log 改 count${this.count}if count0 条件渲染切分支 }) } .width(100%).height(100%).alignItems(HorizontalAlign.Center) } }写鸿蒙 ArkUI 记住build 里 if 不是语句是装饰器绑渲染树分支——if 贬饰器编译期绑渲染树分支1/else 绑分支2运行时按状态选分支渲染不是运行时 if 语句跳转。根因不是语法区别是渲染树绑定 vs 语句执行流的边界——if 贬饰器编译期绑渲染树分支合法 运行时按状态选分支渲染不是语句跳转 if 语句报错边界build 是渲染树不是语句执行流。if/else 二分支渲染用状态切两分支首选if/else if/else 多分支渲染用状态切多分支if 嵌套 if 用多状态组合条件。if 贬饰器绑渲染树分支不是 if 语句是 ArkUI 渎染哲学核心