JSX中如何在DatePicker的handleSubmit中实现页面重定向?
解决React中日期选择后跳转预订页的问题
看起来你在React里处理日期选择后的页面跳转时踩了几个常见的坑,我来帮你梳理清楚问题所在,并给出可行的解决方案。
先分析你之前的错误尝试
1. 编译失败的代码问题
你在handleSubmit里直接调用render的写法完全不对——render是React组件的生命周期方法,只能由React框架调用,不能手动在事件处理函数里执行。而且你的语法也有问题,render里的代码块写法不符合JSX规范,再加上event.preventDefault()放在了render之后,永远不会被执行(因为render里的return会提前终止函数)。
2. 半成功(闪回)的代码问题
你直接在handleSubmit里返回<h1>组件的思路错了:事件处理函数不是渲染函数,返回组件不会触发页面跳转。更关键的是,event.preventDefault()写在了return之后,根本没执行,导致表单触发了默认的提交行为——页面刷新,所以你会看到闪一下空白页,然后原页面重新加载,state里的日期也被清空了。
正确的解决方案(基于React Router)
要实现带状态的页面跳转,你需要借助React Router的路由能力,核心是阻止表单默认提交,然后通过history对象跳转并传递时间戳参数。
步骤1:确保项目已集成React Router
如果还没安装,先执行:
npm install react-router-dom # 或者 yarn add react-router-dom
步骤2:类组件的正确写法(适配你的现有代码)
假设你的日期选择组件是类组件,我们用withRouter高阶组件来获取history对象:
import React from 'react'; import { withRouter } from 'react-router-dom'; import DatePicker from '你的日期选择组件路径'; class DateSelector extends React.Component { state = { value: null // 存储选中日期的午夜时间戳 }; handleDateChange = (date) => { // 将选中日期转为午夜时间戳并存入state const midnightTimestamp = new Date(date.setHours(0,0,0,0)).getTime(); this.setState({ value: midnightTimestamp }); }; handleSubmit = (event) => { // 第一步:必须先阻止表单默认提交!避免页面刷新 event.preventDefault(); const { value } = this.state; if (value) { // 用history.push跳转,把时间戳作为查询参数传递给预订页 this.props.history.push(`/Bookingpage?timestamp=${value}`); // 如果你想用路径参数,先在路由配置里设置:<Route path="/Bookingpage/:timestamp" component={BookingPage} /> // 然后改成:this.props.history.push(`/Bookingpage/${value}`); } }; render() { return ( <form onSubmit={this.handleSubmit}> <DatePicker onChange={this.handleDateChange} value={this.state.value} /> <button type="submit">进入预订页面</button> </form> ); } } // 用withRouter包裹组件,才能拿到history props export default withRouter(DateSelector);
步骤3:预订页(Bookingpage)接收并使用时间戳
方式1:接收查询参数(函数式组件)
import React, { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; function BookingPage() { const location = useLocation(); const [availableSlots, setAvailableSlots] = useState([]); useEffect(() => { // 解析URL里的时间戳参数 const timestamp = new URLSearchParams(location.search).get('timestamp'); if (timestamp) { // 这里调用你的API,用时间戳查询当日可用时段 fetch(`/api/available-slots?date=${timestamp}`) .then(res => res.json()) .then(data => setAvailableSlots(data)) .catch(err => console.error('获取时段失败:', err)); } }, [location.search]); return ( <div className="booking-page"> <h1>选择预订时段</h1> {availableSlots.length > 0 ? ( <ul> {availableSlots.map(slot => ( <li key={slot.id}>{slot.time}</li> ))} </ul> ) : ( <p>加载中...</p> )} </div> ); } export default BookingPage;
方式2:接收路径参数(类组件)
如果用路径参数传递时间戳,预订页可以这样写:
import React from 'react'; class BookingPage extends React.Component { state = { availableSlots: [] }; componentDidMount() { const { timestamp } = this.props.match.params; if (timestamp) { // 调用API查询可用时段 fetch(`/api/available-slots?date=${timestamp}`) .then(res => res.json()) .then(data => this.setState({ availableSlots: data })) .catch(err => console.error('获取时段失败:', err)); } } render() { const { availableSlots } = this.state; return ( <div className="booking-page"> <h1>选择预订时段</h1> {availableSlots.length > 0 ? ( <ul> {availableSlots.map(slot => ( <li key={slot.id}>{slot.time}</li> ))} </ul> ) : ( <p>加载中...</p> )} </div> ); } } export default BookingPage;
关键注意点
- 永远先阻止表单默认提交:
event.preventDefault()必须放在事件处理函数的最前面,避免页面刷新清空state。 - React跳转必须用Router的history:不能通过在事件处理函数里返回组件实现跳转,必须使用
history.push或Redirect组件(Redirect要放在render里)。 - 参数传递要规范:用查询参数或路径参数传递时间戳,不要依赖全局state(除非用Redux等状态管理工具)。
内容的提问来源于stack exchange,提问作者 Deployed DDOS
相关产品推荐
相关产品推荐

