React问题:禁用映射按钮时触发意外重渲染致题目刷新
解决方案
问题核心
你遇到的问题本质是:React中修改状态(比如setDisableButton)会触发组件重渲染,如果getMovie的执行时机和状态更新绑定(比如在useEffect中依赖了disableButton),重渲染就会立刻刷新题目。同时直接操作DOM修改className不符合React状态驱动的理念,重渲染后会被覆盖。
修复步骤
改用状态管理按钮的禁用状态和选中状态,完全通过React状态控制UI,避免直接DOM操作:
- 新增状态变量
import { useState } from 'react'; // 控制所有按钮是否禁用 const [isButtonsDisabled, setIsButtonsDisabled] = useState(false); // 记录用户选中的答案,用于渲染正确/错误样式 const [selectedAnswer, setSelectedAnswer] = useState(null);
- 重构按钮生成函数
不再直接操作DOM,通过状态判断按钮样式:
const createReponse = () => tableauDeReponse .sort((a, b) => a - b) .map((ele) => { let btnClass = "Reponse-container"; // 根据选中状态和答案正确性添加样式 if (selectedAnswer === ele) { btnClass += ele === bonneReponse ? " goodAnswer" : " wrongAnswer"; } return ( <button disabled={isButtonsDisabled} className={btnClass} onClick={() => handleClick(ele)} type="button" key={ele} > {ele} </button> ); });
- 重写点击事件处理函数
通过状态控制流程,确保只有延迟结束后才刷新题目:
const handleClick = (selectedEle) => { // 1. 立即禁用所有按钮,防止多选 setIsButtonsDisabled(true); // 2. 记录选中的答案,触发样式更新 setSelectedAnswer(selectedEle); // 3. 延迟1.5秒后刷新题目并重置状态 delay(1500).then(() => { getMovie(); // 生成新题目 setSelectedAnswer(null); // 清除选中状态 setIsButtonsDisabled(false); // 重新激活按钮 }); };
关键说明
- 所有UI变化都由状态驱动,避免了直接DOM操作和重渲染的冲突。
- 设置
isButtonsDisabled(true)会触发重渲染,但此时getMovie并未执行,不会立即刷新题目。 - 确保
getMovie只在延迟回调中执行,和状态更新解耦,彻底解决提前刷新的问题。
内容的提问来源于stack exchange,提问作者Boivinos
相关产品推荐
相关产品推荐

