title: [ISSUE-0016] RatingStars 对异常 rating 输入不稳健 description: "RatingStars 对 NaN / 字符串 / 越界 rating 输入不稳健" tags: [issue] created: 2026-05-26 updated: 2026-05-26 type: issue status: fixed severity: minor
[ISSUE-0016] RatingStars 对异常 rating 输入不稳健¶
相关源码:
src/sections/page/merchant-detail-drawer.tsx发现途径:v0.10.19 代码审查
用户感知的现象¶
理论上:
- rating = "4.5"(字符串)→ rating.toFixed(1) 报 TypeError
- rating = NaN → 显示 0 颗星但数字显示 "NaN"
- rating = -1 / 7(异常值)→ 星条 layout 错乱
实际上 caller 已守 row.rating != null && row.rating > 0,挡住了大部分。但 row.rating = "4.5" 满足 > 0(字符串自动转),仍会进入。
根因分析¶
function RatingStars({ rating, count }: { rating: number; count?: number }) {
const filled = Math.floor(rating); // NaN 时为 NaN
const half = rating - filled >= 0.3 ...;
const empty = 5 - filled - half; // 可能为负数
// ...
<Typography>{rating.toFixed(1)}</Typography> // 非 number 报错
}
修复方案¶
函数顶部 clamp + Number 转换:
function RatingStars({ rating, count }: { rating: number | string; count?: number }) {
const r = Math.max(0, Math.min(5, Number(rating) || 0));
if (r === 0) return null; // 0 星不显示
const filled = Math.floor(r);
const half = r - filled >= 0.3 && r - filled < 0.8 ? 1 : 0;
const empty = Math.max(0, 5 - filled - half);
// ...
<Typography>{r.toFixed(1)}</Typography>
}
改动文件¶
| 文件 | 改了什么 |
|---|---|
src/sections/page/merchant-detail-drawer.tsx |
RatingStars clamp [0,5] + Number 转换 + empty max(0) |
验证方式¶
注入异常数据测试: - rating = "4.5" → 应显示 4.5 颗星 - rating = NaN → 应不显示组件 - rating = 7 → 应显示满 5 星 - rating = -1 → 应不显示
如何避免再犯¶
- 任何接收 number 的 UI 组件,函数头 1 行 clamp + 类型转换
- 写 React 组件时假设 props 会被「污染」:可能传 null/undefined/string/NaN,全用 Number() / String() 转
- 0 值视情况决定是否渲染:评分 0 通常表示"无评分",应隐藏
相关问题¶
- 无