【发布时间】:2021-12-27 14:15:01
【问题描述】:
我正在使用最新的 react 版本 6.0.2 我正在关注 lama dev youtube 视频,以使用 react 制作购物网站。 我想将状态(使用 redux)及其数据传递到成功页面,然后使用“购物车”及其“产品”及其所有信息来进一步保存订单。 在视频中,这是使用“useHistory()”方法完成的,我正在使用 useNavigate()(这适用于 React 路由器 dom v6)。我正在努力进一步解析数据以获取显示为空的所需购物车和产品。我得到了状态,但购物车和产品在开发工具的 Redux 状态下显示为空。
我的成功页面是这样的
const Success = () => {
const location = useLocation();
console.log(location); // to see what state are being passed after placing an order
const data = location.state;
const cart = location.state.cart;
console.log(data, cart);
const currentUser = useSelector((state) => state.user.currentUser);
const [orderId, setOrderId] = useState(null);
useEffect(() => {
const createOrder = async () => {
try {
const res = await userRequest.post("/orders", {
userId: currentUser._id,
products: cart.products.map((item) => ({
productId: item._id,
quantity: item.quantity,
})),
amount: cart.total,
address: data.billing_details.address,
});
setOrderId(res.data._id);
} catch (err) {
console.log(err);
}
};
data && createOrder();
}, [cart, data, currentUser]);
return (
<Container>
{orderId
? `Order has been created successfully. Your order number is ${orderId}`
: `????Successfull. Your order is being prepared...`}
<Link to="/">
<Button>Go to Homepage</Button>
</Link>
</Container>
);
};
export default Success;
我的购物车页面如下所示
const Cart = () => {
const cart = useSelector((state) => state.cart);
const [stripeToken, setStripeToken] = useState(null);
// const history = useNavigate();
const navigate = useNavigate();
const onToken = (token) => {
setStripeToken(token);
};
//token returns on successful order placing
console.log(stripeToken);
useEffect(() => {
const makeRequest = async () => {
try {
const res = await userRequest.post("/checkout/payment", {
tokenId: stripeToken.id,
amount: cart.total * 100,
});
navigate("/success", { state: res, cart });
} catch (err) {
console.log(err);
}
};
stripeToken && makeRequest();
}, [stripeToken, cart.total, navigate]);
return (
<Container>
<Navbar />
<Announcement />
<Wrapper>
<Title>YOUR BAG</Title>
<Top>
<TopBotton>CONTINUE SHOPPING</TopBotton>
<TopTexts>
<TopText>
<ShoppingBag
style={{ margin: '-3px 2px', color: 'teal' }}
/>{' '}
BAG(3)
</TopText>
<TopText>
<Favorite
style={{ margin: '-3px 2px', color: 'red' }}
/>{' '}
WISHLIST(0)
</TopText>
</TopTexts>
<TopBotton type="filled">CHECKOUT NOW</TopBotton>
</Top>
<Bottom>
<Info>
{cart.products.map((product) => (
<Product>
<ProductDetail>
<Image src={product.img} />
<Details>
<ProductName>
<b>Product:</b> {product.title}
</ProductName>
<ProductId>
<b>ID:</b> {product._id}
</ProductId>
<ProductColor color={product.color} />
<ProductSize>
<b>Size:</b> {product.size}
</ProductSize>
</Details>
</ProductDetail>
<PriceDetail>
<Hr />
<ProductAmountContainer>
<Add />
<ProductAmount>
{product.quantity}
</ProductAmount>
<Remove />
</ProductAmountContainer>
<ProductPrice>
₹ {product.price * product.quantity}
</ProductPrice>
</PriceDetail>
</Product>
))}
<Hr />
{/* <Product>
<ProductDetail>
<Image src="https://images.pexels.com/photos/9558241/pexels-photo-9558241.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260"/>
<Details>
<ProductName><b>Product:</b> HAKURA T-SHIRT</ProductName>
<ProductId><b>ID:</b> 124541</ProductId>
<ProductColor color="grey"/>
<ProductSize><b>Size:</b> M</ProductSize>
</Details>
</ProductDetail>
<PriceDetail>
<Hr/>
<ProductAmountContainer>
<Add/>
<ProductAmount>2</ProductAmount>
<Remove/>
</ProductAmountContainer>
<ProductPrice>$ 30</ProductPrice>
</PriceDetail>
</Product> */}
</Info>
<Summary>
<SummaryTitle>ORDER SUMMARY</SummaryTitle>
<SummaryItem>
<SummaryItemText>Subtotal: </SummaryItemText>
<SummaryItemPrice>₹ {cart.total}</SummaryItemPrice>
</SummaryItem>
<SummaryItem>
<SummaryItemText>
Estimated Shipping:{' '}
</SummaryItemText>
<SummaryItemPrice>₹ 150.90</SummaryItemPrice>
</SummaryItem>
<SummaryItem>
<SummaryItemText>
Shipping Discount:{' '}
</SummaryItemText>
<SummaryItemPrice>-₹ 150.90</SummaryItemPrice>
</SummaryItem>
<Hr />
<SummaryItem type="total">
<SummaryItemText>Total: </SummaryItemText>
<SummaryItemPrice>₹ {cart.total}</SummaryItemPrice>
</SummaryItem>
<StripeCheckout
name="Ecofelx"
image="https://avatars.githubusercontent.com/Ardent10"
billingAddress
shippingAddress
description={`Your total is ₹ ${cart.total}`}
currency="INR"
amount={cart.total * 100}
token={onToken}
stripeKey={KEY}
>
<Button>CHECKOUT NOW</Button>
</StripeCheckout>
</Summary>
</Bottom>
</Wrapper>
<Footer />
</Container>
);
};
export default Cart;
这里看一下redux截图。我想要购物车、它的产品并获取它们各自的 ID,以便我可以在后端下订单并运送到它的地址。 Redux screenshot
编辑:我更新的方法 我意识到 cart.jsx 中的 useSelector() 用于获取状态购物车,然后该购物车在成功页面上传递,该页面进一步用于下订单。我再次使用 useSelector() 成功地在那里抓住了购物车,而不是通过导航。
//我的购物车.jsx
const cart = useSelector((state)=>state.cart);
const [stripeToken, setStripeToken] = useState(null);
// const history = useNavigate();
const navigate = useNavigate();
const onToken = (token) =>{
setStripeToken(token);
}
//token returns on successful order placing
// console.log(stripeToken);
useEffect(() => {
const makeRequest = async () => {
try {
const res = await userRequest.post("/checkout/payment", {
tokenId: stripeToken.id,
amount: 500,
});
navigate("/success", {state:res});
}
catch(err)
{
console.log(err);
}
};
stripeToken && makeRequest();
}, [stripeToken, cart.total , navigate]);
// 我的success.jsx 页面现在
const location = useLocation();
// console.log(location); // to see what state are being passed after placing an order
const cart = useSelector((state)=>state.cart);
const data = location.state;
console.log(data,cart);
const currentUser = useSelector((state)=>state.user.currentUser);
const [orderId, setOrderId] = useState(null);
console.log(orderId);
useEffect(() => {
const createOrder = async () => {
try {
const res = await userRequest.post("/orders", {
userId: currentUser._id,
products: cart.products.map((item) => ({
productId: item._id,
quantity: item.quantity,
})),
amount: cart.total,
address: data.billing_details.address,
});
setOrderId(res.data._id);
}
catch(err) {
console.log(err);
}
};
data && createOrder();
}, [cart, data, currentUser]);
return (
<Container>
{orderId
? `????Order has been created successfully. Your order number is ${orderId}`
: `????Successfull. Your order is being prepared...`}
<Link to="/">
<Button>Go to Homepage</Button>
</Link>
</Container>
);
};
结果截图-> result console
【问题讨论】:
-
除了通过路由状态将
cart状态传递到成功页面之外,您的 redux 状态与发送路由状态有什么关系尚不清楚。你能澄清你的问题/问题的这一部分吗? -
发送数据和购物车的原因是当成功页面显示给用户时,后端需要将产品的所有详细信息和下订单的用户发送到订单路线,以便成功下订单。我将数据发布到订单路线。我是 react 和 redux 的新手,这是我的第一个项目。这是 [1:21:00] 的视频 youtube.com/watch?v=y66RgYMAgSo 是我的主要问题所在。该视频是在 react-router-dom 5.3.0 上制作的,我使用的是 6.0.2。
-
感谢您的宝贵时间。我是初学者,我尝试使用您的答案来实现,但我的 redux 开发工具显示 mw 选择的购物车和产品,但在我的 cart.jsx 页面数据和购物车和未定义中。我现在坚持了3天。还是谢谢你。
-
我从 youtube 视频中看不到您的问题。正如我在回答中建议的那样,他们甚至将状态传递为
data。问题是您的Success组件没有看到正确的路由状态吗?您正在使用函数组件和 React 钩子,所以我看不出在这方面react-router-dom版本之间会有多大差异。你能分享一个更完整的代码示例吗?你是如何声明路线的?你能为我们提供足够的背景来重现这个问题吗?您能否将您的代码分叉到一个 running 代码框中,以便我们可以实时检查和调试? -
是的,我可以看到在我的 MongoDB 集合中放置的相应订单,您介意在我完成这个项目之前问您更多疑问吗?有一些我想自定义的功能在视频中没有完成。
标签: javascript reactjs redux react-router