问题描述
我正在使用 Redux 学习 MERN 堆栈,但在尝试在订单页面中打印 order._id 时遇到了问题,但我无法做到。我不确定这里缺少什么会导致问题。我无法打印与当前订单相关的任何内容。任何帮助,将不胜感激。下面是我的代码;
Order.js
const mongoose = require('mongoose');
const orderSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,required: true,ref: 'User',},orderItems: [
{
name: { type: String,required: true },quantity: { type: Number,image: { type: String,price: { type: Number,product: {
type: mongoose.Schema.Types.ObjectId,ref: 'Product',],shippingInfo: {
address: { type: String,city: { type: String,postalCode: { type: String,country: { type: String,paymentMethod: {
type: String,paymentResult: {
id: { type: String },status: { type: String },update_time: { type: String },email_address: { type: String },taxPrice: {
type: Number,default: 0.0,shippingPrice: {
type: Number,totalPrice: {
type: Number,isPaid: {
type: Boolean,default: false,paidAt: {
type: Date,isDelivered: {
type: Boolean,deliveredAt: {
type: Date,{
timestamps: true,}
)
module.exports = mongoose.model('Order',orderSchema)
OrderController.js
// Get single order => /apI/Order/:id
exports.getSingleOrder = catchAsyncErrors(async (req,res,next) => {
const order = await Order.findOne({_id: req.params.id}).populate('user','firstName email')
console.log(req.params.id)
if (!order) {
return next(new ErrorHandler('No Order found with this ID',404))
}
res.status(200).json({
success: true,order
})
})
**OrderActions.js**
// get ordetails for a single order by order/:id
export const getorderDetails = (id) => async (dispatch,getState) => {
try {
dispatch({ type: GET_ORDER_REQUEST });
const { data } = await axios.get(`/apI/Order/${id}`)
dispatch({
type: GET_ORDER_SUCCESS,payload: data,})
} catch (error) {
dispatch({
type: GET_ORDER_FAIL,payload: error.response.data.message
})
}
}
orderReducers.js
export const orderDetailsReducer = ( state = { loading: true,orderItems: [],shippingAddress: {} },action) => {
switch (action.type) {
case GET_ORDER_REQUEST:
return {
...state,loading: true,};
case GET_ORDER_SUCCESS:
return {
loading: false,order: action.payload,};
case GET_ORDER_FAIL:
return {
loading: false,error: action.payload,};
default:
return state;
}
};
export const orderPayReducer = (state = {},action) => {
switch (action.type) {
case ORDER_PAY_REQUEST:
return {
loading: true,};
case ORDER_PAY_SUCCESS:
return {
loading: false,success: true,};
case ORDER_PAY_FAIL:
return {
loading:false,};
case ORDER_PAY_RESET:
return {};
default:
return state;
}
};
**Order.js**
import React,{Fragment,useEffect,useState } from 'react'
import MetaData from '../MetaData';
import { Link } from 'react-router-dom';
import { usedispatch,useSelector } from 'react-redux'
import { PayPalButton } from 'react-paypal-button-v2'
import axios from 'axios';
import { getorderDetails,payOrder,deliverOrder } from '../actions/OrderActions';
import { ORDER_PAY_RESET } from '../constants/OrderConstants';
const Order = ({ match,history }) => {
const orderId = match.params.id
const [sdkReady,setSdkReady ] = useState(false)
const dispatch = usedispatch()
const { user } = useSelector(state => state.auth)
const orderDetails = useSelector(state => state.orderDetails)
const { order,loading,error } = orderDetails
console.log("This is order details for orderpage destructering :",order);
const orderPay = useSelector((state) => state.orderPay)
const { loading: loadingPay,success: successpay } = orderPay
const orderDeliver = useSelector((state) => state.orderDeliver)
const { loading: loadingDeliver,success: successDeliver} = orderDeliver
useEffect(() => {
if(!user) {
history.push('/login');
}
const addPayPalScript = async () => {
const { data: clientId } = await axios.get('/api/config/paypal')
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = `https://www.paypal.com/sdk/js?client-id=${clientId}`
script.async = true
script.onload = () => {
setSdkReady(true)
}
document.body.appendChild(script)
}
if (!order || successpay || successDeliver || order._id !== orderId) {
dispatch({ type: ORDER_PAY_RESET })
//dispatch({ type: ORDER_DELIVER_RESET })
dispatch(getorderDetails(orderId))
} else if (!order.isPaid) {
if (!window.paypal) {
addPayPalScript()
} else {
setSdkReady(true)
}
}
},[dispatch,orderId,successpay,successDeliver,order])
const successpaymentHandler = (paymentResult) => {
console.log(paymentResult)
dispatch(payOrder(orderId,paymentResult))
}
const deliverHandler = () => {
dispatch(deliverOrder(order._id));
};
return (
<div className="container">
<MetaData title={'Confirm Order'} />
<div className="row d-flex justify-content-between">
<div className="col-12 col-lg-8 mt-5 order-details">
<h1 className="my-5">Order # ${order._id}</h1>
{order.user.firstName}
<h4 className="mb-4">Shipping Info</h4>
<p><b>Name:</b> {user && user.name}</p>
{/* <p><b>Phone:</b> {shippingInfo && shippingInfo.phoneNo}</p>
<p className="mb-4"><b>Address:</b>{shippingDetails}</p>
<p><b>Amount:</b> ${totalPrice}</p> */}
<hr />
<h4 className="mb-3">PAYMENT METHOD</h4>
<strong> Method:</strong>
<h4 className="mt-4">ORDER ITEMS</h4>
<Fragment>
<hr />
<div className="cart-item my-1" >
<div className="row">
<div className="col-4 col-lg-2">
<img src="" alt="Laptop" height="45" width="65" />
</div>
<div className="col-5 col-lg-6">
{/* <Link to={`/product/${item.product}`}></Link> */}
</div>
<div className="col-4 col-lg-4 mt-4 mt-lg-0">
<p></p>
</div>
</div>
</div>
<hr />
</Fragment>
</div>
<div className="col-12 col-lg-3 my-4">
<div id="order_summary">
<h4>Order Summary</h4>
<hr />
<p>Items: <span className="order-summary-values"></span></p>
<p>Shipping: <span className="order-summary-values"></span></p>
<p>Tax: <span className="order-summary-values"></span></p>
<hr />
<p>Total: <span className="order-summary-values"></span></p>
<hr />
<button id="checkout_btn" className="btn btn-primary btn-block" onClick={successpaymentHandler}>Place Order</button>
</div>
</div>
</div>
</div>
)
}
export default Order
解决方法
大家好,我通过执行 {orderId} 而不是 ${order._id} 解决了这个问题,谢谢
,它们是您的减速器和反应组件中的问题 按顺序Reducer.js
<Select
className="drop-down"
options={data?.map((data,index) => ({
value: data.username,label: data.username,id: index,}))}
name="user"
value={data.username}
onChange={handleSelectChangeL}
placeholder="User Name"
theme={(theme) => ({
...theme,colors: {
...theme.colors,text: "black",primary25: "#d6fdf7",primary: "#0bb7a7",primary50: "#d6fdf7",},})}
></Select>
<button
className="dash-button-1"
type="submit"
variant="contained"
onClick={reset}
>
Reset
</button>
在你的反应组件中使用
case GET_ORDER_SUCCESS:
return{
...state,loading: false,orderItems: action.payload // in reducer initial state youe define orderItems
not order
}
以及您想在何处访问 orderItems 详细信息,例如 _id、名称和其他内容
使用基于索引的 orderItems,如
const {orderItems,loading,error} = orderDetails //same as in reducer you define orderItems not order
希望这能解决您的问题