React注册功能useState异步更新导致history.push强制跳转问题求解
问题根本原因
React的状态更新是异步批量执行的,你在HandleRegister函数内调用setFailed(true)之后,本次函数执行周期内读取的Failed状态还是当前渲染周期的旧值(初始为false),所以不管校验结果如何,判断if (Failed)永远不成立,都会走注册跳转的分支。
最优解决方案
不要在本次状态更新的同步逻辑中直接依赖state的值做判断,先在函数内部用临时变量存储校验结果,再根据临时变量的结果执行对应逻辑,同时同步更新state即可。
另外校验用户名是否存在可以用更简洁的Array.some()方法,不需要遍历整个数组,修改后的代码如下:
const HandleRegister = () => { const Users = auth.getUsers(); // 先用临时变量存储校验结果,不直接依赖state const isUsernameExist = Users.some(({ username }) => username === newUserName); if (isUsernameExist) { setFailed(true); console.log("Error!"); } else { setFailed(false); auth.setUsers(newUserName, newUserPassword); setnewUserName(""); setnewUserPassword(""); history.push("/login"); } };
额外优化建议
- 当前的登录逻辑也存在隐患:
forEach遍历完所有用户后,无论是否匹配到正确的账号密码,最终都会执行setFailed(true),就算匹配成功跳转了,状态也会被更新为失败,建议同样改用some判断匹配结果后再执行对应逻辑。 - 密码输入框的type应该改为
password而不是text,避免明文泄露。 - 注册、提交操作可以增加表单校验,比如用户名密码不能为空的判断。
内容的提问来源于stack exchange,提问作者Forshank
相关产品推荐
相关产品推荐

