如何在 React 中正确重置单选按钮的选中状态

本文讲解在 react 中使用受控组件方式管理单选按钮时,如何确保每次提交后所有选项均被彻底取消选中,避免因状态未及时同步导致 ui 显示异常的问题。

在 React 中,

必须作为受控组件使用,即其 checked 状态完全由 React 状态(如 selectedAnswer)驱动,而非依赖 DOM 操作或默认行为。你当前代码中存在两个关键问题:
  1. 错误的 checked 属性写法

    {...{ selectedAnswer } != null ? "checked" : null}

    这段语法不合法 —— 展开对象 { selectedAnswer } 返回的是 { selectedAnswer: value },与 null 比较恒为 true,且 "checked" 字符串无法作为布尔属性生效。正确写法应为显式布尔表达式:

    checked={selectedAnswer === questionsJSON.questions[num].answers[0]}
  2. 重置时机不当
    你将 setSelectedAnswer(null) 放在 useEffect 中响应 setNum,但 useEffect 是异步执行的,而 UI 渲染发生在状态更新后立即进行。若 selectedAnswer 仍为上一题的值(如 "A"),新题渲染时未及时清空,就会出现「视觉已选中但状态为 null」的错位现象。

✅ 正确做法是:在用户点击提交时同步重置状态,确保下一次渲染前 selectedAnswer 已归零:

const onClickPassRadio = (e) => {
  e.preventDefault();
  setSelectedAnswer(""); // ✅ 立即清空,保证下次渲染无残留选中
  setNum(randomNumberInRange(10));
};

同时,修正所有

的 checked 属性(以第一个为例):
 setSelectedAnswer(e.target.value)}
  checked={selectedAnswer === questionsJSON.questions[num].answers[0]} // ✅ 正确受控
/>

⚠️ 注意事项:

  • 初始状态建议设为 ""(空字符串)而非 null,避免与有效答案值(如 null 可能是合法选项)混淆;
  • 所有单选按钮必须共用相同的 name(你已做到:name="answer"),否则无法互斥;
  • 若题目答案数组含重复值(如第 0 和第 3 项 value 相同),会导致多选同时高亮 —— 请检查 questionsJSON.questions[num].answers 是否真正唯一。

通过同步重置 + 正确受控绑定,即可彻底解决「提交后仍显示选中」的 UI 不一致问题。