React组件传值问题:如何将CartContainer总价传递给PaymentContainer?
问题原因
当前代码中,CartContainer里直接渲染的PaymentContainer和路由跳转后创建的PaymentContainer是两个完全独立的组件实例。路由跳转后,React会重新初始化PaymentContainer,此时没有任何props传入,所以totalAmount为undefined。
解决方案
方案1:利用现有全局状态管理 推荐
既然已经在用StateProvider,直接把总价存入全局状态,PaymentContainer直接从全局读取即可。
步骤1:更新Reducer
在reducer.js中新增设置总价的action类型:
export const actionType = { // 保留原有action SET_TOTAL_PRICE: "SET_TOTAL_PRICE", }; const reducer = (state, action) => { switch (action.type) { // 保留原有case case actionType.SET_TOTAL_PRICE: return { ...state, totalPrice: action.totalPrice, }; default: return state; } }; export default reducer;
步骤2:CartContainer中同步总价到全局
修改useEffect,计算完成后把总价dispatch到全局状态,同时修正依赖数组避免无限循环:
useEffect(() => { let totalPrice = cartItems.reduce((accumulator, item) => { return accumulator + item.qty * item.price; }, 0); setTot(totalPrice); // 同步到全局状态 dispatch({ type: actionType.SET_TOTAL_PRICE, totalPrice: totalPrice, }); }, [cartItems]); // 只依赖cartItems,总价随购物车商品变化自动更新
步骤3:PaymentContainer从全局获取总价
修改PaymentContainer,直接从useStateValue读取总价:
import React from "react"; import { useStateValue } from "../context/StateProvider"; const PaymentContainer = () => { const [{ totalPrice }] = useStateValue(); const containerAmount = totalPrice + 2.5; // 加上配送费 return ( <div> <h2>Total: ${containerAmount}</h2> </div> ); }; export default PaymentContainer;
步骤4:移除冗余代码
删掉CartContainer中多余的PaymentContainer渲染:
// 删掉这段 <div> <PaymentContainer totalAmount={tot} /> </div>
方案2:路由传参 适合简单场景
如果不想改动全局状态,可通过路由的state传递参数:
步骤1:修改CartContainer的Link
<Link to={{ pathname: '/payment', state: { totalAmount: tot } }} > <motion.button whileTap={{ scale: 0.8 }} type="button" class...>Check Out</motion.button> </Link>
步骤2:PaymentContainer获取路由参数
用useLocation钩子读取传递的state:
import React from "react"; import { useLocation } from "react-router-dom"; const PaymentContainer = () => { const location = useLocation(); // 加默认值避免直接访问/payment时出错 const totalAmount = location.state?.totalAmount || 0; const containerAmount = totalAmount + 2.5; return ( <div> <h2>Total: ${containerAmount}</h2> </div> ); }; export default PaymentContainer;
方案3:URL查询参数 适合刷新页面仍保留数据的场景
如果需要页面刷新后总价不丢失,可使用URL查询参数:
步骤1:修改CartContainer的Link
<Link to={`/payment?total=${tot}`}> <motion.button whileTap={{ scale: 0.8 }} type="button" class...>Check Out</motion.button> </Link>
步骤2:PaymentContainer获取查询参数
用useSearchParams钩子读取参数:
import React from "react"; import { useSearchParams } from "react-router-dom"; const PaymentContainer = () => { const [searchParams] = useSearchParams(); // 转换为数字并设置默认值 const totalAmount = parseFloat(searchParams.get('total')) || 0; const containerAmount = totalAmount + 2.5; return ( <div> <h2>Total: ${containerAmount}</h2> </div> ); }; export default PaymentContainer;
内容的提问来源于stack exchange,提问作者SomeUser
相关产品推荐
相关产品推荐

