微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取有效负载在产品详细信息页面上不起作用React、Redux

如何解决获取有效负载在产品详细信息页面上不起作用React、Redux

我为此花了 2 天时间,但不知道为什么。 我正在使用 React 构建一个电子商务网站,并且没有加载有效负载,只有“加载”状态被卡住为真,然后没有从后端获取任何数据。我已经尽我所能,发现只有“ProductInfo”页面试图从“localhost:3000/api/products”获取数据(后端端口是 5000,“Home”页面正确地从 5000 获取数据)

有人能找出哪里错了吗?


操作:

export const listProducts = () => async (dispatch) => {
    dispatch({
        type: ActionTypes.PRODUCTS_LIST_REQUEST
    });

    try {
        const { data } = await Axios.get('/api/products');
        dispatch({ type: ActionTypes.PRODUCTS_LIST_SUCCESS,payload: data });
    } catch(error) {
        dispatch({ type: ActionTypes.PRODUCTS_LIST_FAIL,payload: error.message});
    }
};

export const detailsProduct = (productId) => async (dispatch) => {
    dispatch({ type: ActionTypes.PRODUCT_DETAILS_REQUEST,payload: productId });
    try {
      const { data } = Axios.get(`/api/products/${productId}`);
      await dispatch({ type: ActionTypes.PRODUCT_DETAILS_SUCCESS,payload: data });
    } catch (error) {
      dispatch({ 
        type: ActionTypes.PRODUCT_DETAILS_FAIL,payload: 
        error.response && error.response.data.message 
        ? error.response.data.message
        : error.message
      });
    }
  };

减速器:

export const productListReducer = (state={ loading: true,products: []},action) => {
    switch(action.type) {
        case PRODUCTS_LIST_REQUEST:
            return { loading: true };
        case PRODUCTS_LIST_SUCCESS:
            return { loading: false,products: action.payload };
        case PRODUCTS_LIST_FAIL:
            return { loading: false,error: action.payload}
        default:
            return state;
    }
};

export const productDetailsReducer = (state={ loading: true },action) => {
    switch(action.type) {
        case PRODUCT_DETAILS_REQUEST:
            return { loading: true };
        case PRODUCT_DETAILS_SUCCESS:
            return { loading: false,product: action.payload};
        case PRODUCT_DETAILS_FAIL:
            return { loading: false,error: action.payload };
        default:
            return state;
    }
};

App.js

function App() {
  return (
    <browserRouter>
        <Header />
        <Route path="/" component={Home} exact />
        <Route path="/product/:id" component={ProductInfo} exact />
        <Footer />
    </browserRouter>
  );
}

export default App;

import React,{ useState,useEffect } from 'react';
import { usedispatch,useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import ReactStars from 'react-rating-stars-component';
import Loading from '../LoadingComponent';
import MessageBox from '../MessageBoxComponent';
import { SELLERS } from '../../shared/sellers';
import './ProductInfo.css';
import { detailsProduct} from '../../redux/actionCreators';


function ProductInfo(props) {
  
    const dispatch = usedispatch();
    const productId = props.match.params.id;
    const productDetails = useSelector((state) => state.productDetails);
    const { loading,error,product } = productDetails;
    
    console.log(productDetails);
    useEffect((productId) => {
        dispatch(detailsProduct(productId));
    },[dispatch,productId]);



    const seller = SELLERS.find((seller) => seller._id === product.sellerId);
    
    const [ showImage,setShowImage ] = useState(product.imageUrl[0]);

    const renderImages = product.imageUrl.map(image => (
        <div className="info__smallImgBox" onClick={() => setShowImage(image)}>
            <img 
                src={image} 
                className="info__smallImg" 
                alt={product.name+' image'}
            />
        </div>
    ));


    return (
        
        <div className="info__container">
            <Link to="/"><div className="info__goBack"><span><i className="fa fa-angle-left" /> BACK TO MAIN</span></div></Link>
            {loading?  <Loading />
            : error? <MessageBox variant="danger">{error}</MessageBox>
            :(<div className="info__content">
                <div className="info__main">
                    <div className="info__imageBox">
                        <img src={showImage} className="info__image" alt={product.name}/>
                        <div className="info__imageCarousel">
                            {renderImages}
                        </div>
                    </div>
                    <div className="info__description">
                        <h2>{product.name}</h2>
                        <div className="info__ratings row">
                            <ReactStars  
                                count={5}
                                value={product.rating}
                                size={15}
                                activeColor="yellow"
                                edit={false}
                            />
                            <span> {product.numReviews + (product.numReviews>0? " reviews" : " review")}</span>
                        </div>
                        <h3>${product.price}</h3>
                        <h4><span className="head">Materials </span>  {product.material}</h4>
                        <h4><span className="head">Description </span> {product.description}</h4>
                    </div>
                </div>
                <div className="info__action">
                    <div className="info__seller row">
                        <h3>Seller</h3>
                        <h3>{seller.name}</h3>
                    </div>
                
                    <div className="info__ratings row" style={{paddingLeft:0}}>
                        <ReactStars 
                            count={5}
                            value={product.rating}
                            size={15}
                            activeColor="yellow"
                            edit={false}
                        />
                        <h3> {product.numReviews + (product.numReviews>0? " reviews" : " review")}</h3>
                    </div>
                    <div className="row">
                        <h3>Price</h3>
                        <h3>${product.price}</h3>
                    </div>
                    <div className="row"> 
                        <h3>Status</h3>
                        <h3>{product.countInStock > 5 ? (<span className="">In Stock</span>) : product.countInStock > 0? (<span className="red">Only {product.countInStock} In Stock</span>): (<span className="red">Unavailable</span>)}</h3>
                    </div>
                    <div className="row" style={{margin: '2rem 0'}}>
                        <label for="qty">Qty</label>
                        <select name="qty" style={{color: 'black',fontSize:"1.8rem",height: '2.9rem',padding: '3px 10px'}} >
                            <option >select</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>
                            <option value="7">7</option>
                            <option value="8">8</option>
                            <option value="9">9</option>
                            <option value="10">10</option>
                        </select>
                    </div>
                    <div className="row center">
                        <button className="">ADD TO CART</button>
                    </div>
                </div>
            </div>)}
        </div>
    )
}


export default ProductInfo;

==========

错误消息:未捕获的类型错误:无法读取未定义的属性“sellerId”

解决方法

我认为这里可能存在一些问题。但这是我注意到的。

  1. 当你从后端获取数据时,你必须为 Axios 指定完整的 url。否则,它将尝试从当前 url 中获取它。因此,需要更改此代码以包含完整的后端网址:

从这里:

const { data } = await Axios.get('/api/products');

这样的事情:

const { data } = await Axios.get('https://my-backend.com/api/products');

对后端的其他调用也是如此。

  1. 在您的 ProductInfo 组件中,您试图从产品对象中获取 id。但是这个变量不存在。我认为您的意思是 productDetails 或直接使用 productId

const seller = SELLERS.find((seller) => seller._id === product.sellerId);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。