如何在React中将表单数据传递至汇总页并显示购物车总价?
实现建议
1. 先把表单改成受控组件,管理输入状态
你的表单目前都是无控组件,无法获取用户输入的数据,首先要用useState来统一管理所有表单字段的状态:
import React, { useContext, useState } from "react"; import { StoreComponent } from "../../components/StoreComponents"; import { Button } from "@mui/material"; import { useNavigate } from "react-router-dom"; // 导入路由跳转钩子 import "../../styles/Order.css"; function Order() { const { getCartTotal } = useContext(StoreComponent); const navigate = useNavigate(); // 初始化表单状态,对应所有输入字段 const [formData, setFormData] = useState({ firstname: "", lastname: "", email: "", address: "", zipcode: "", city: "", phone: "", cardnumber: "", expired: "", cvc: "" }); // 统一处理输入变化 const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; // 提前计算总价,避免重复调用getCartTotal const cartTotal = getCartTotal(); const finalTotal = cartTotal === 0 ? 0 : cartTotal + 2; // 提交表单并跳转到汇总页 const handleSubmit = (e) => { e.preventDefault(); // 把表单数据和总价通过路由状态传递 navigate("/summary", { state: { formData, cartTotal, finalTotal } }); }; return ( <form className="place-order" onSubmit={handleSubmit}> <div className="place-order-left"> <p className="title">Delivery information</p> <div className="multi-fields"> <input type="text" placeholder="Firstname" name="firstname" value={formData.firstname} onChange={handleInputChange} /> <input type="text" placeholder="Lastname" name="lastname" value={formData.lastname} onChange={handleInputChange} /> </div> <input type="email" placeholder="E-mail" name="email" value={formData.email} onChange={handleInputChange} /> <div className="multi-fields"> <input type="text" placeholder="Address" name="address" value={formData.address} onChange={handleInputChange} /> </div> <div className="multi-fields"> <input type="text" placeholder="zipcode" name="zipcode" value={formData.zipcode} onChange={handleInputChange} /> <input type="text" placeholder="city" name="city" value={formData.city} onChange={handleInputChange} /> </div> <input type="text" placeholder="phone" name="phone" value={formData.phone} onChange={handleInputChange} /> </div> <div className="place-order-middle"> <p className="title">Payment</p> <div className="multi-fields"> <input type="text" placeholder="cardnumber" name="cardnumber" value={formData.cardnumber} onChange={handleInputChange} /> </div> <div className="multi-fields"> <input type="text" placeholder="expired" name="expired" value={formData.expired} onChange={handleInputChange} /> <input type="text" placeholder="CVC-code" name="cvc" value={formData.cvc} onChange={handleInputChange} /> </div> </div> <div className="place-order-right"> <div className="cart-total"> <h2>Cart Total</h2> <div> <div className="cart-totals-details"> <p>Sum</p> <p>{cartTotal} $</p> </div> <hr /> <div className="cart-totals-details"> <p>Fee</p> <p>{cartTotal === 0 ? 0 : 2} $</p> </div> <hr /> <div className="cart-totals-details"> <b>Total</b> <b>{finalTotal} $</b> </div> </div> <Button variant="contained" type="submit">Pay now</Button> </div> </div> </form> ); } export default Order;
2. 创建汇总页面,接收并展示数据
新建Summary组件,通过useLocation获取路由传递的状态,渲染用户输入信息和总价:
import React from "react"; import { useLocation } from "react-router-dom"; function Summary() { const location = useLocation(); const { formData, cartTotal, finalTotal } = location.state || {}; // 防止直接访问汇总页的情况 if (!formData) { return <div>No order data found</div>; } return ( <div className="summary-page"> <h1>Order Summary</h1> <div className="delivery-info"> <h2>Delivery Information</h2> <p><strong>Name:</strong> {formData.firstname} {formData.lastname}</p> <p><strong>Email:</strong> {formData.email}</p> <p><strong>Address:</strong> {formData.address}, {formData.city} {formData.zipcode}</p> <p><strong>Phone:</strong> {formData.phone}</p> </div> <div className="payment-info"> <h2>Payment Details</h2> <p><strong>Card Number:</strong> **** **** **** {formData.cardnumber.slice(-4)}</p> <p><strong>Expiry:</strong> {formData.expired}</p> </div> <div className="total-info"> <h2>Order Total</h2> <div className="cart-totals-details"> <p>Sum</p> <p>{cartTotal} $</p> </div> <hr /> <div className="cart-totals-details"> <p>Fee</p> <p>{cartTotal === 0 ? 0 : 2} $</p> </div> <hr /> <div className="cart-totals-details"> <b>Total</b> <b>{finalTotal} $</b> </div> </div> </div> ); } export default Summary;
3. 额外优化点
- 全局上下文替代路由传参:如果你的
StoreComponent上下文已经用于全局状态管理,也可以把表单数据存入上下文,汇总页直接通过useContext获取,适合需要在多个组件共享订单数据的场景。 - 表单验证:在
handleSubmit中添加必填字段检查,比如姓名、邮箱、地址等,确保用户输入完整后再跳转。 - 敏感数据处理:银行卡号这类敏感信息不要在前端持久化存储,展示时只显示后四位即可。
内容的提问来源于stack exchange,提问作者Lambada
相关产品推荐
相关产品推荐

