React中非托管属性与useState托管属性结合使用时错误不展示问题
问题根因
isInputTouched是组件内部的普通临时变量,没有被React状态托管,每次组件重新渲染时整个函数会重新执行,该变量会被重新初始化为false,你在提交事件里给它赋的true值不会跨渲染周期保留。- 你调用
setIsValidForm(false)时,isValidForm的初始值就是false,React对状态更新会做浅比较校验,如果新值和旧值完全相等,默认会跳过本次重渲染,你预期的UI更新流程根本没有触发。 - 就算触发了重渲染,受第一条问题影响
isInputTouched已经被重置为false,(!isValidForm && isInputTouched)的判断条件依然不成立,错误提示不会展示。
修复方案
- 将
isInputTouched改为React状态托管,保证值在重渲染之间可以保留:
// 替换原有的let isInputTouched = false const [isInputTouched, setIsInputTouched] = useState(false);
所有原代码中给isInputTouched = true赋值的位置,都改为调用setIsInputTouched(true)。
2. 调整isValidForm的更新逻辑,避免设置相同值导致跳过渲染:
可以将isValidForm初始值改为null,校验失败时设置为false,校验成功时设置为true;也可以简化逻辑,直接用一个状态存错误提示:
const [errorMsg, setErrorMsg] = useState(""); // 提交校验失败时 setErrorMsg("please enter valid email and password"); setUsername(""); setPassword(""); // 校验成功时清空错误 setErrorMsg(""); // JSX中直接判断错误提示是否存在即可 {errorMsg && <p className="text text-center text-danger">{errorMsg}</p>}
内容的提问来源于stack exchange,提问作者Amit Gupta
相关产品推荐
相关产品推荐

