如何在使用React Router DOM v6.2.1的React类组件中实现表单提交后跳转至首页
解决React Router v6中表单提交后无法重定向的问题
嗨,我看到你在React Router v6里遇到了表单提交后重定向的问题,这是因为v6和之前的v5版本在路由API上有很大的变化,你之前用的this.props.history.push("/")在v6里已经不生效了——原因是v6不再自动给路由组件注入history、location这些props,所以this.props.history其实是undefined,自然没办法完成跳转。
下面给你两种可行的解决方案,你可以根据自己的情况选择:
方案一:将AddSubscriber转为函数组件,使用useNavigate钩子(推荐)
React现在更推荐函数组件结合Hooks的写法,这种方式更简洁,也完全符合React Router v6的设计思路:
import React, { useState } from 'react'; import Header from './Header'; import './AddSubscriber.css'; import { Link, useNavigate } from "react-router-dom"; export default function AddSubscriber(props) { // 用useState替代类组件的state const [subscriberData, setSubscriberData] = useState({ id: 0, name: '', phone: '' }); const onChangeHandler = (event) => { // 根据输入框name更新对应状态 const { name, value } = event.target; setSubscriberData(prev => ({ ...prev, [name]: value })); }; // 获取navigate函数 const navigate = useNavigate(); const onFormSubmitted = (event) => { event.preventDefault(); props.addSubscribers(subscriberData); // 重置表单 setSubscriberData({ id: 0, name: "", phone: '' }); // 执行重定向 navigate("/"); }; return ( <div> <Header heading="Add Subscriber"/> <div className="component-body-container"> <Link to="/"> <button className="custom-btn">Back</button> </Link> <form className="subscriber-form" onSubmit={onFormSubmitted}> {/* 补充表单输入框,记得设置name属性并绑定值和事件 */} <input type="text" name="name" value={subscriberData.name} onChange={onChangeHandler} placeholder="Enter Name" /> <input type="tel" name="phone" value={subscriberData.phone} onChange={onChangeHandler} placeholder="Enter Phone Number" /> <button type="submit" className="custom-btn add-btn">Add</button> </form> </div> </div> ); }
方案二:给类组件传递navigate函数(如果不想改函数组件)
如果你暂时不想把类组件改成函数组件,可以通过父组件把navigate函数传递给子组件:
第一步:修改PhoneDirectory为函数组件(类组件无法直接使用Hooks)
import React, { useState } from 'react'; import AddSubscriber from './AddSubscriber'; import ShowSubscribers from './ShowSubscribers'; import { BrowserRouter, Route, Routes, useNavigate } from 'react-router-dom'; export default function PhoneDirectory() { const [subscribersList, setSubscribersList] = useState([]); const addSubscribers = (subscriber) => { // 示例添加逻辑:生成唯一ID后加入列表 const newSubscriber = { ...subscriber, id: Date.now() }; setSubscribersList(prev => [...prev, newSubscriber]); }; const deleteSubscribers = (subscriberId) => { const updatedList = subscribersList.filter(item => item.id !== subscriberId); setSubscribersList(updatedList); }; // 获取navigate函数 const navigate = useNavigate(); return ( <BrowserRouter> <Routes> <Route exact path='/' element={<ShowSubscribers deleteSubscribers={deleteSubscribers} subscribersList={subscribersList}/>} /> <Route exact path='/add' element={<AddSubscriber addSubscribers={addSubscribers} navigate={navigate}/>} /> </Routes> </BrowserRouter> ); }
第二步:在AddSubscriber类组件中使用传递过来的navigate
import React from 'react'; import Header from './Header'; import './AddSubscriber.css'; import { Link } from "react-router-dom"; export default class AddSubscriber extends React.Component { constructor() { super(); this.state = { id: 0, name:'', phone:'' }; } onChangeHandler = (event) => { const { name, value } = event.target; this.setState(prev => ({ ...prev, [name]: value })); }; onFormSubmitted = (event) =>{ event.preventDefault(); this.props.addSubscribers(this.state); this.setState({id:0, name:"", phone:''}); // 使用父组件传递的navigate函数跳转 this.props.navigate("/"); }; render() { return ( <div> <Header heading="Add Subscriber"/> <div className="component-body-container"> <Link to="/"> <button className="custom-btn">Back</button> </Link> <form className="subscriber-form" onSubmit={this.onFormSubmitted}> {/* 你的表单元素 */} <input type="text" name="name" value={this.state.name} onChange={this.onChangeHandler} placeholder="Enter Name" /> <input type="tel" name="phone" value={this.state.phone} onChange={this.onChangeHandler} placeholder="Enter Phone Number" /> <button type="submit" className="custom-btn add-btn">Add</button> </form> </div> </div> ); } }
额外方案:使用<Navigate>组件实现重定向
还有一种方式是通过状态控制渲染<Navigate>组件,当表单提交后设置一个重定向状态,然后在render里判断并渲染跳转组件:
在AddSubscriber的state里添加redirect: false,然后修改onFormSubmitted:
onFormSubmitted = (event) =>{ event.preventDefault(); this.props.addSubscribers(this.state); this.setState({id:0, name:"", phone:'', redirect: true}); };
然后在render方法最前面添加判断:
render() { if (this.state.redirect) { return <Navigate to="/" />; } // 原有渲染内容 }
记得要导入Navigate组件:import { Link, Navigate } from "react-router-dom";
总结
推荐优先选择方案一,因为函数组件+Hooks是React的未来趋势,代码更简洁易维护。如果实在要保留类组件,可以选择方案二或者方案三。
内容的提问来源于stack exchange,提问作者abhishek narayan
相关产品推荐
相关产品推荐

