React表单调用e.preventDefault后仍刷新问题求助
解决React表单提交页面刷新的问题
Hey there! Let's dig into why your form is still refreshing the page even after trying those propagation stops— I see where the issues are:
核心问题分析
The main culprit here isn't the event propagation methods you tried, but three key missteps:
- You're calling
e.preventDefault()after analert(which can introduce unexpected behavior, even if it's synchronous) - Your
setStatesyntax is incorrect, which breaks your axios request too - You're not accounting for React's asynchronous
setStatewhen sending your POST request
修复后的代码
修改App.js中的handleSubmit函数
handleSubmit(e, firstName, lastName, email, phone, postalCode) { // 首先阻止表单默认提交行为(这才是阻止页面刷新的关键!) e.preventDefault(); // 传播阻止代码可以保留,但不是必须的除非你有其他冒泡事件需要处理 e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); alert('Submitted: ' + firstName + ", " + lastName); // 正确更新userVote状态对象,而不是把字段平铺到state根节点 this.setState({ step: 3, userVote: { ...this.state.userVote, FirstName: firstName, LastName: lastName, Email: email, MobileNumber: phone, ZipCode: postalCode } }, () => { // 在setState的回调中发送请求,确保状态已经更新完成 axios.post('http://localhost:54467/api/poll/vote', this.state.userVote) .then(response => { console.log("VI HAR SENDT INN !!!:", response.data) }) .catch(err => console.log("Error", err)) }) }
为什么这样修复?
e.preventDefault()必须优先执行: 表单提交的默认行为是刷新页面,你需要在任何其他代码(比如alert)之前调用这个方法,确保浏览器不会触发默认刷新。之前的顺序虽然理论上可能生效,但把它放在最前面是绝对安全的最佳实践。- 正确更新嵌套状态: 你的原代码把
userVote的字段直接展开到state根节点,导致this.state.userVote根本不会包含新提交的表单数据。通过嵌套更新userVote对象,你才能确保axios发送的是最新的用户信息。 - 异步setState的回调: React的
setState是异步的,如果你在setState之后立即调用axios,你拿到的还是更新前的this.state.userVote。把请求放在setState的回调函数里,就能保证状态已经完全更新。
另外,你之前用的stopPropagation相关方法其实和页面刷新没有直接关系——这些方法是用来阻止事件向上冒泡到父元素,或者阻止同元素上的其他事件监听器执行。阻止页面刷新只需要e.preventDefault()就够了。
内容的提问来源于stack exchange,提问作者Terje Nygård
相关产品推荐
相关产品推荐

