You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中作为Props的onSubmit与onClick差异及表单提交状态异常问题

问题现象

作为React和JavaScript新手,开发Web认证功能时遇到以下问题:

  • 子组件中,按钮通过onClick调用父组件的login方法,能正常更新父组件的loginStatus,Layout组件显示true;
  • 但表单通过onSubmit调用同一方法后,控制台自动刷新,Layout仍显示false。

相关代码

父组件(index.js)

const [loginStatus, setLoginStatus] = useState(false);

function handlelogout() {
  setLoginStatus(false);
  console.log("logged out");
}  

const login=()=>{
  console.log("loginstatus"+loginStatus)
  setLoginStatus(true);
  console.log("login")
} 
return(
  <BrowserRouter>
    <Layout loginstatus={loginStatus} logout={handlelogout} />
    <Routes>
      <Route path="/" /> 
      <Route index element={<App />}/>
      <Route path="login" element={<Login login={login } />}/>
      <Route path="register" element={<Register />}/>
    </Routes>
  </BrowserRouter>
)

子组件(login.js)

return (
  <>
    <div className='Registerform'>
      <h3>Login Form</h3><br></br>
      <Form onSubmit={props.login} > {/* 这里失效 */}
          <Form.Group className="mb-3" controlId="formBasicName">
              <Form.Label>Username</Form.Label>
              <Form.Control type="username" placeholder="Enter your username" />
          </Form.Group><br></br>

          <Form.Group className="mb-3" controlId="formBasicPassword">
              <Form.Label>Password</Form.Label>
              <Form.Control type="password" placeholder="Password" />
          </Form.Group><br></br>

          <Button variant="primary" type="submit">
              Submit
          </Button>
      </Form>
    </div>
    
    <Button onClick={props.login} variant="primary">Primary</Button> {/* 这里正常工作 */}
  </>
)

Layout组件相关代码

const loginStatus=props.loginstatus
console.log("layout: "+loginStatus)

控制台日志

  • 点击按钮(正常情况):
loginstatusfalse
login
layout: true
layout: true
  • 点击表单提交(异常情况):
loginstatusfalse
login

(控制台自动刷新)
layout:false
layout:false
原因分析

这是HTML表单的默认提交行为导致的:当表单触发submit事件时,浏览器会自动刷新页面,重新加载整个应用。虽然login函数确实执行了setLoginStatus(true),但页面刷新后所有组件会重新挂载,useState(false)会把loginStatus重置为初始值false,所以Layout组件显示false。

而按钮的onClick事件不会触发页面刷新,状态更新后能正常保留。

解决方案

需要在表单提交时阻止浏览器的默认刷新行为,有两种常用方式:

方式一:修改父组件的login函数,接收事件参数并阻止默认行为

const login=(e)=>{
  e.preventDefault(); // 阻止表单默认提交行为
  console.log("loginstatus"+loginStatus)
  setLoginStatus(true);
  console.log("login")
} 

方式二:在子组件中包装onSubmit处理函数

// login.js中修改Form的onSubmit
<Form onSubmit={(e) => {
  e.preventDefault(); // 先阻止默认行为
  props.login(); // 再调用父组件的login方法
}} >

两种方式任选其一即可,修改后表单提交不会刷新页面,loginStatus的更新会正常保留,Layout组件也会显示true。

内容的提问来源于stack exchange,提问作者user20112858

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:05:24