React餐厅预订应用:API返回的bookingId无法在结果页正常渲染
问题分析与解决方案
问题根源
- 表单页
useParams无效:BookingForm页面的路由中并未定义id参数,所以const { id } = useParams();拿到的始终是undefined,点击链接自然会跳转到/booking/undefined。 - 未捕获预订返回ID:提交表单成功后,没有从API返回结果中提取新生成的
bookingId,而是错误使用了不存在的路由参数。
修复步骤
1. 修改BookingForm.tsx代码
移除无用的useParams,改用useNavigate实现跳转,同时存储新生成的预订ID:
import axios from "axios"; import { useEffect, useState } from "react"; import { ChangeEvent, SyntheticEvent } from "react"; import { Link, useNavigate } from "react-router-dom"; import { IBookings } from "../models/IBookings"; export const BookingForm = () => { const navigate = useNavigate(); const [restaurants, setRestaurants] = useState<IBookings[]>([]); const [newBookingId, setNewBookingId] = useState<string | null>(null); const [addBooking, setAddBooking] = useState({ restaurantId: '', date: '', time: '', numberOfGuests: 0, customer: { name: '', lastname: '', email: '', phone: '' } }); useEffect(() => { getRestaurants(); }, []); const getRestaurants = async () => { try { const response = await axios.get<IBookings[]>( `https://school-restaurant-api.azurewebsites.net/restaurant/65c6276ee125e85f5e15b79f` ); setRestaurants(response.data); } catch (error) { console.error("Error fetching restaurants:", error); } }; const handleInputChange = (e: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => { const { name, value } = e.target; if (name.startsWith("customer.")) { setAddBooking(prevState => ({ ...prevState, customer: { ...prevState.customer, [name.split('.')[1]]: value } })); } else { const newValue = name === 'numberOfGuests' ? parseInt(value) : value; setAddBooking(prevState => ({ ...prevState, [name]: newValue })); } }; const onSubmit = (e: SyntheticEvent<HTMLFormElement, SubmitEvent>) => { e.preventDefault(); axios.post("https://school-restaurant-api.azurewebsites.net/booking/create", addBooking) .then((response) => { console.log('New booking created successfully:', response.data); // 从API返回结果中提取预订ID(字段名请根据实际返回调整) const bookingId = response.data.id; setNewBookingId(bookingId); // 自动跳转到结果页 navigate(`/booking/${bookingId}`); }) .catch((error) => { console.error('Error creating booking:', error); }); }; return ( <div className="m-4 border-8 border-pink-600"> <h2>Make your reservation</h2> <form action="" onSubmit={onSubmit}> {/* 表单输入部分保持不变 */} <div> <label>Choose restaurant</label> <select name="restaurantId" value={addBooking.restaurantId} onChange={handleInputChange}> <option value="0">None</option> <option value="65c6276ee125e85f5e15b79f">Happy Dumpling</option> </select> </div> <div> <label>Date</label> <input type="date" placeholder="Add Date" name="date" value={addBooking.date} onChange={handleInputChange} /> </div> <div> <label>Time</label> <select name="time" value={addBooking.time} onChange={handleInputChange} > <option value="0">0</option> <option value="18.00">18:00</option> <option value="21.00">21:00</option> </select> </div> <div> <label>How many seats</label> <select name="numberOfGuests" value={addBooking.numberOfGuests} onChange={handleInputChange} > <option value="0">0</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> </select> </div> <div> <label>Name</label> <input type="text" placeholder="Name" name="customer.name" value={addBooking.customer.name} onChange={handleInputChange} /> </div> <div> <label>LastName</label> <input type="text" placeholder="LastName" name="customer.lastname" value={addBooking.customer.lastname} onChange={handleInputChange} /> </div> <div> <label>Email</label> <input type="text" placeholder="Email" name="customer.email" value={addBooking.customer.email} onChange={handleInputChange} /> </div> <div> <label>Phone</label> <input type="text" placeholder="Phone" name="customer.phone" value={addBooking.customer.phone} onChange={handleInputChange} /> </div> <button className="btn btn-block" type="submit" value="Save Task"> Book a table </button> <br /> {/* 仅在创建成功后显示链接 */} {newBookingId && ( <Link to={`/booking/${newBookingId}`}>Se din bokning här</Link> )} </form> </div> ); };
2. 确认路由配置有效性
确保你的路由规则包含/booking/:id,示例如下:
import { Routes, Route } from 'react-router-dom'; import { BookingForm } from './BookingForm'; import { BookingRender } from './BookingRender'; function App() { return ( <Routes> <Route path="/" element={<BookingForm />} /> <Route path="/booking/:id" element={<BookingRender />} /> </Routes> ); }
关键说明
- 表单提交成功后,必须从
response.data中提取API返回的预订ID(字段名可能是id或bookingId,请根据实际返回调整)。 - 移除表单页中无用的
useParams,因为该页面路由无id参数,无法获取有效值。 - 可选择自动跳转或创建成功后显示链接,两种方式都能确保传递正确的
bookingId。
内容的提问来源于stack exchange,提问作者gritoverflow
相关产品推荐
相关产品推荐

