React中三元语句未按预期工作的原因排查
问题根源:JavaScript运算符优先级
这个问题其实是运算符优先级在暗中捣乱!咱们一步步拆解来看:
前两个div为什么正常工作?
前两个div的写法是:
<div className={"guage-segment default " + (this.health() === 'default' ? 'active' : '')}>Default</div>
这里的三元表达式 (this.health() === 'default' ? 'active' : '') 是作为一个整体和前面的字符串 "guage-segment default " 做拼接的。括号明确了运算顺序:先判断健康状态,得到'active'或者空字符串,再和前面的类名字符串拼接,所以结果完全符合预期。
第三个div为什么失效?
第三个div的写法是:
<div className={"guage-segment ok " + (this.health() === "ok") ? "active" : ""}>Ok</div>
这里踩了运算符优先级的坑:JavaScript中加法运算符+的优先级高于条件运算符?:。代码的实际执行顺序变成了:
- 先计算
"guage-segment ok " + (this.health() === "ok"):因为this.health()返回'default',所以(this.health() === "ok")是false,拼接后得到字符串"guage-segment ok false"。 - 再用这个字符串作为三元表达式的判断条件:由于非空字符串在JS里属于真值(truthy),所以三元表达式会直接返回
"active",不管你的健康状态是不是ok。
这就导致第三个div永远都会加上active类,完全偏离了预期效果!
修复方法
有两种简单可靠的修复方式:
- 给整个三元表达式加括号,强制它先执行:
<div className={"guage-segment ok " + ((this.health() === "ok") ? "active" : "")}>Ok</div>
- 使用模板字符串(更推荐,可读性更强,不容易再踩优先级坑):
<div className={`guage-segment ok ${this.health() === "ok" ? "active" : ""}`}>Ok</div>
内容的提问来源于stack exchange,提问作者Kyle Woolley
相关产品推荐
相关产品推荐

