ReactJS使用react-router-dom点击表单提交按钮跳转到首页失败如何解决
问题原因
你目前的写法存在两个典型错误:
- React Hook 只能在组件顶层作用域调用,不能在
saveEntity这类事件回调函数内部调用useHistory,不符合Hook的使用规则,本身会触发语法报错。 <Redirect>组件只有作为组件渲染方法的返回值时才会生效,事件回调函数的返回值不会被React解析渲染,所以返回这个组件没有任何效果。
修复方案
首先确认你使用的react-router-dom版本,对应选择方案:
react-router-dom v6 版本
v6已移除useHistory,替换为useNavigate,需要在组件顶层调用Hook获取跳转方法:
import { useNavigate } from 'react-router-dom'; import { useState } from 'react'; const YourComponent = () => { // 组件顶层调用Hook const navigate = useNavigate(); const [realm, setRealm] = useState(); const [ente, setEnte] = useState(); const saveEntity = (event, errors, values) => { // 如果出现页面刷新情况,可加此行阻止默认提交 // event.preventDefault(); console.log('values .', values); if (values.realm) { setRealm(values.realm); } if (values.ente) { setEnte(values.ente); } if (values.realm) { console.log('dentro ', values.realm); // 直接调用跳转方法 navigate('/'); } }; return ( <div> <AvForm onSubmit={saveEntity}> {/* 其余表单内容 */} </AvForm> </div> ) }
react-router-dom v5 版本
使用useHistory实现,同样需要在组件顶层调用Hook:
import { useHistory } from 'react-router-dom'; import { useState } from 'react'; const YourComponent = () => { // 组件顶层调用Hook const history = useHistory(); const [realm, setRealm] = useState(); const [ente, setEnte] = useState(); const saveEntity = (event, errors, values) => { // 如果出现页面刷新情况,可加此行阻止默认提交 // event.preventDefault(); console.log('values .', values); if (values.realm) { setRealm(values.realm); } if (values.ente) { setEnte(values.ente); } if (values.realm) { console.log('dentro ', values.realm); // 直接调用跳转方法 history.push('/'); } }; return ( <div> <AvForm onSubmit={saveEntity}> {/* 其余表单内容 */} </AvForm> </div> ) }
可选:使用Redirect组件实现跳转
如果你需要用Redirect组件的方式实现,可通过状态控制组件渲染:
import { Redirect } from 'react-router-dom'; import { useState } from 'react'; const YourComponent = () => { const [shouldRedirect, setShouldRedirect] = useState(false); const [realm, setRealm] = useState(); const [ente, setEnte] = useState(); const saveEntity = (event, errors, values) => { console.log('values .', values); if (values.realm) { setRealm(values.realm); } if (values.ente) { setEnte(values.ente); } if (values.realm) { console.log('dentro ', values.realm); // 修改状态触发重渲染 setShouldRedirect(true); } }; // 状态为true时先渲染Redirect组件完成跳转 if (shouldRedirect) { return <Redirect to="/" /> } return ( <div> <AvForm onSubmit={saveEntity}> {/* 其余表单内容 */} </AvForm> </div> ) }
内容的提问来源于stack exchange,提问作者Jack23
相关产品推荐
相关产品推荐

