跳转至

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 通常表示"无评分",应隐藏

相关问题