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
相关产品推荐
相关产品推荐

