React表单handleSubmit未触发 无法跳转动态日期参数路由
问题排查与修复方案
你的代码存在3个核心问题,直接导致提交失效、跳转失败、数据拉取异常:
- 事件回调中返回
<Navigate>组件完全不会生效:<Navigate>是声明式导航组件,只有被渲染到JSX树中时才会触发跳转,在handleSubmit这类事件处理函数里return的JSX不会被React挂载,完全不执行逻辑。同时你没有阻止表单的默认提交行为,点击提交按钮会触发表单默认的整页刷新,中断所有前端逻辑。 - 事件绑定和路径拼接错误:你把提交逻辑绑在了按钮的
onClick上,用户按回车提交表单时不会触发逻辑;跳转路径写死为/guage/:input,没有把用户输入的实际日期值替换到路径里,就算跳转成功也会跳到字面量的:input路径,而不是带实际日期的路由。 - 仪表盘组件的数据请求逻辑错误:
fetchPosts函数没有获取路由中传递的日期参数,接口URL里的{date}只是普通字符串,没有做变量替换;同时react-query的queryKey没有携带日期参数,切换不同日期时会直接读缓存,不会拉取对应日期的新数据。
修复步骤
1. 重构CalendarPicker组件
React Router v6在类组件中无法直接使用useNavigate钩子,通过高阶组件注入导航方法,同时修正事件绑定、默认行为阻止、路径拼接逻辑:
import React from 'react'; import { useNavigate } from 'react-router-dom'; // 高阶组件:给类组件注入navigate编程式导航方法 function withNavigate(Component) { return function WrappedComponent(props) { const navigate = useNavigate(); return <Component {...props} navigate={navigate} />; }; } class CalendarPicker extends React.Component { constructor(props) { super(props); this.state = { input: '' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ [event.target.name]: event.target.value }); } handleSubmit(event) { // 必须阻止表单默认刷新行为 event.preventDefault(); // 动态拼接目标路径,执行编程式跳转 this.props.navigate(`/guage/${this.state.input}`); } render() { return ( <div> {/* 提交事件绑定在form标签上,兼容回车提交场景 */} <form onSubmit={this.handleSubmit}> <label> 日期 <input type="text" name="input" value={this.state.input} onChange={this.handleChange} placeholder="请输入YYYY-MM-DD格式日期" required /> <button variant="primary" type="submit"> 提交 </button> </label> </form> </div> ); } } export default withNavigate(CalendarPicker);
2. 修正DelayGuage组件
从路由参数中读取日期,动态拼接接口地址,修正react-query缓存逻辑:
import React from "react"; import { Chart } from "react-google-charts"; import axios from "axios"; import { useQuery } from 'react-query'; import { useParams } from "react-router-dom"; // 接收date参数,动态请求对应日期的数据 async function fetchDelayData(date) { const { data } = await axios.get( `http://102.12.11.102:5000/reports/${date}/agencies` ); const parsedData = data.agencies[0].kpis.map((item) => [ "Delay Index", item.kpi_value * 100 ]); return [["Label", "Value"], ...parsedData]; } export const gaugeOptions = { width: 480, height: 480, redFrom: 90, redTo: 100, yellowFrom: 75, yellowTo: 90, minorTicks: 5 }; export function DelayGuage() { // 从路由中提取日期参数 const { date } = useParams(); // queryKey加入date依赖,日期变化时自动重新请求;加enabled控制避免空参数发请求 const { data, status } = useQuery( ["delayGaugeData", date], () => fetchDelayData(date), { enabled: !!date } ); return ( status === "success" && ( <Chart chartType="Gauge" width="100%" height="400px" data={data} options={gaugeOptions} /> ) ); } export default DelayGuage;
3. 核对路由配置
确保路由表中已经配置了带日期参数的路由,否则无法匹配到对应页面、拿不到参数:
// 路由配置示例 <Route path="/guage/:date" element={<DelayGuage />} />
注意:你代码里的路径写的是
guage,和英文单词gauge(仪表盘)拼写不一致,如果后续要改路径,记得同步修改跳转逻辑和路由配置,避免出现404。
内容的提问来源于stack exchange,提问作者roastyroach
相关产品推荐
相关产品推荐

