Node.js中MySQL UPDATE执行异常:首次点击无数据更新
问题分析与解决:首次点击按钮无法更新数据库,双击才生效
问题核心
首次点击按钮调用handleStatus函数时,后端返回affectedRows: 0,无数据更新;第二次点击则能成功修改1行数据。
原因分析
前端handleStatus里的两个Axios请求是异步并行执行的,再加上setEmail是异步更新状态的,导致了时序问题:
- 触发
Axios.get("/login")后,请求还未返回结果,Axios.post("/voted")就已经执行 - 此时
userEmail还是初始的空字符串,后端收到空邮箱参数,找不到匹配的数据库行,因此更新0行 - 第一次点击完成后,
get请求返回,setEmail更新了状态;第二次点击时,userEmail已经是正确的邮箱值,post请求就能成功找到对应行完成更新
修复方案
确保拿到正确的邮箱后再发送更新请求,两种实现方式:
方案1:嵌套回调
const [userEmail, setEmail] = useState('') const handleStatus = () => { Axios.get("http://localhost:3001/login").then((response) => { if (response.data.loggedIn === true) { const email = response.data.user[0].email setEmail(email) // 拿到邮箱后再发送post请求 Axios.post('http://localhost:3001/voted', {email: email}).then((response) => { console.log(response) }) } }) }
方案2:使用async/await(更清晰的异步流程)
const [userEmail, setEmail] = useState('') const handleStatus = async () => { try { const loginRes = await Axios.get("http://localhost:3001/login") if (loginRes.data.loggedIn === true) { const email = loginRes.data.user[0].email setEmail(email) const voteRes = await Axios.post('http://localhost:3001/voted', {email: email}) console.log(voteRes) } } catch (err) { console.error(err) } }
额外建议
- 后端可加入参数校验,当收到空邮箱时返回明确错误(比如
res.status(400).send({error: '邮箱不能为空'})),方便前端排查问题 - 避免依赖前端状态存储用户信息,登录后可将邮箱存在
localStorage或通过请求头传递,减少异步请求的依赖
内容的提问来源于stack exchange,提问作者Parzival
相关产品推荐
相关产品推荐

