简体   繁体   English

React redux 中的数据映射有问题?

[英]Having problem in data mapping in react redux?

We are currently building an e-commerce website using react-redux.我们目前正在使用 react-redux 构建一个电子商务网站。 We use mock JSON data in order to develop the product and category page using JSON-server.我们使用模拟 JSON 数据来使用 JSON-server 开发产品和类别页面。 But While changing the data with real data.但是在用真实数据改变数据的同时。 then we have a problem with typeError: item.variant is undefined.那么我们遇到了 typeError 的问题:item.variant 是未定义的。

Anyone help to solve this problem.任何人都可以帮助解决这个问题。

mock data:模拟数据:

{
  "product": [
    {
      "id": 1,
      "name": "Flare Dress",
      "price": 120,
      "salePrice": 200,
      "discount": 50,
      "pictures": [
        "/assets/images/fashion/product/1.jpg",
        "/assets/images/fashion/product/21.jpg",
        "/assets/images/fashion/product/36.jpg",
        "/assets/images/fashion/product/12.jpg"
      ],
      "shortDetails": "Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem,",
      "description": {
        "Ram": "4gb",
        "size": "large"
      },
      "stock": 16,
      "new": true,
      "sale": true,
      "colors": ["yellow", "gray", "green"],
      "size": ["M", "L", "XL"],
      "tags": ["nike", "caprese"],
      "rating": 4,
      "variants": [
        {
          "color": "yellow",
          "images": "/assets/images/fashion/product/1.jpg"
        },
        {
          "color": "gray",
          "images": "/assets/images/fashion/product/21.jpg"
        },
        {
          "color": "green",
          "images": "/assets/images/fashion/product/36.jpg"
        }
      ]
    },
    {
      "id": 2,
      "name": "Wrap Dress",
      "price": 330.0,
      "salePrice": 165.0,
      "discount": 50,
      "pictures": [
        "/assets/images/fashion/product/15.jpg",
        "/assets/images/fashion/product/7.jpg",
        "/assets/images/fashion/product/9.jpg",
        "/assets/images/fashion/product/13.jpg"
      ],
      "shortDetails": "unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem,",
      "description": {
        "Ram": "4gb",
        "type": "personal",
        "hacker": "world",
        "size": "extralarge"
      },
      "stock": 6,
      "new": true,
      "sale": false,
      "category": "women",
      "colors": ["gray", "orange"],
      "size": ["M", "L", "XL"],
      "tags": ["caprese", "puma"],
      "rating": 5,
      "variants": [
        {
          "color": "gray",
          "images": "/assets/images/fashion/product/15.jpg"
        },
        {
          "color": "orange",
          "images": "/assets/images/fashion/product/7.jpg"
        }
      ]
    },
    {
      "id": 3,
      "name": "Danim Jeans",
      "price": 500.0,
      "salePrice": 250.0,
      "discount": 50,
      "pictures": [
        "/assets/images/fashion/product/32.jpg",
        "/assets/images/fashion/product/2.jpg",
        "/assets/images/fashion/product/25.jpg",
        "/assets/images/fashion/product/26.jpg"
      ],
      "shortDetails": "Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem,",
      "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
      "stock": 12,
      "new": false,
      "sale": false,
      "category": "women",
      "colors": ["blue", "white", "yellow"],
      "size": ["M", "L", "XL"],
      "tags": ["puma"],
      "rating": 4,
      "variants": [
        {
          "color": "blue",
          "images": "/assets/images/fashion/product/32.jpg"
        },
        {
          "color": "white",
          "images": "/assets/images/fashion/product/2.jpg"
        },
        {
          "color": "yellow",
          "images": "/assets/images/fashion/product/25.jpg"
        }
      ]
    },
    {
      "id": 4,
      "name": "Waist Dress",
      "price": 180.0,
      "salePrice": 360.0,
      "discount": 50,
      "pictures": [
        "/assets/images/fashion/product/5.jpg",
        "/assets/images/fashion/product/12.jpg",
        "/assets/images/fashion/product/31.jpg",
        "/assets/images/fashion/product/18.jpg"
      ],
      "shortDetails": "Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem,",
      "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
      "stock": 10,
      "new": true,
      "sale": true,
      "category": "women",
      "colors": ["pink", "gray", "green"],
      "size": ["M", "L", "XL"],
      "tags": ["lifestyle"],
      "rating": 4,
      "variants": [
        {
          "color": "pink",
          "images": "/assets/images/fashion/product/5.jpg"
        },
        {
          "color": "gray",
          "images": "/assets/images/fashion/product/12.jpg"
        },
        {
          "color": "green",
          "images": "/assets/images/fashion/product/31.jpg"
        }
      ]
    }
  ]

real data:真实数据:

{
  "products": [
    {
      "id": 1,
      "active": true,
      "slug": "try",
      "sku": "009993",
      "name": "Samsung s10",
      "price": 220.0,
      "effective_price": 234.0,
      "price_unit": "US Dollar",
      "unit": "pieces",
      "short_description": "My phone",
      "description": "Samsung phone new brand.",
      "for_sale": false,
      "for_sale_percent": 0.0,
      "for_sale_price": 0.0,
      "creation_date": "2020-04-11T14:32:37.397890Z",
      "deliverable": true,
      "stock_amount": 1.0,
      "stock_unit": "pieces",
      "weight": 1.0,
      "weight_unit": "",
      "height": null,
      "height_unit": "",
      "length": null,
      "length_unit": "",
      "width": null,
      "width_unit": "",
      "tax_type": 1,
      "manufacturer": "Samsung",
      "active_sku": true,
      "active_short_description": true,
      "active_description": true,
      "active_effective_price": true,
      "active_dimension": true,
      "active_weight": true,
      "specification": {
        "RAM": "2GB",
        "Display size": "10inch"
      },
      "primary_category": 2,
      "images": [
        {
          "product": 1,
          "name": "try",
          "image_file": "http://eversoftgroup.ddns.net:8000/media/products/before_married_salary_after_married_salary_tVIeusG.jpg"
        },
        {
          "product": 1,
          "name": "dsa",
          "image_file": "http://eversoftgroup.ddns.net:8000/media/products/Unbenannt3.JPG"
        },
        {
          "product": 1,
          "name": "hello",
          "image_file": "http://eversoftgroup.ddns.net:8000/media/main-qimg-e93a7956e2e492201b56d11d8db867bf.png"
        }
      ]
    },
    {
      "id": 2,
      "active": true,
      "slug": "lgmob",
      "sku": "38387",
      "name": "LG Mobile",
      "price": 265.0,
      "effective_price": null,
      "price_unit": "Nepalese Rupee",
      "unit": "23",
      "short_description": "A new mobile",
      "description": "This is a new mobile of LG.",
      "for_sale": false,
      "for_sale_percent": 0.0,
      "for_sale_price": 0.0,
      "creation_date": "2020-04-15T15:14:24.583204Z",
      "deliverable": true,
      "stock_amount": 4.0,
      "stock_unit": "pieces",
      "weight": 1.0,
      "weight_unit": "",
      "height": null,
      "height_unit": "",
      "length": null,
      "length_unit": "",
      "width": null,
      "width_unit": "",
      "tax_type": 1,
      "manufacturer": "LG",
      "active_sku": true,
      "active_short_description": true,
      "active_description": true,
      "active_effective_price": true,
      "active_dimension": true,
      "active_weight": true,
      "specification": {
        "RAM": "3GB",
        "Display size": "5 inch"
      },
      "primary_category": 2,
      "images": []
    }
  ]
}

component:零件:

    import React, { Component } from "react";
    import Slider from "react-slick";
    import "../common/index.scss";
    import { connect } from "react-redux";

    // import custom Components
    import Service from "./common/service";
    import BrandBlock from "./common/brand-block";
    import NewProduct from "../common/new-product";
    import Breadcrumb from "../common/breadcrumb";
    import DetailsWithPrice from "./common/product/details-price";
    import DetailsTopTabs from "./common/details-top-tabs";
    import { addToCart, addToCartUnsafe, addToWishlist } from "../../actions";
    import ImageZoom from "./common/product/image-zoom";
    import SmallImages from "./common/product/small-image";

    class RightSideBar extends Component {
      constructor() {
        super();
        this.state = {
          nav1: null,
          nav2: null,
        };
      }

      componentDidMount() {
        this.setState({
          nav1: this.slider1,
          nav2: this.slider2,
        });
      }

      render() {
        const {
          symbol,
          item,
          addToCart,
          addToCartUnsafe,
          addToWishlist,
        } = this.props;
        console.log(item.name);
        var products = {
          slidesToShow: 1,
          slidesToScroll: 1,
          dots: false,
          arrows: true,
          fade: true,
        };
        var productsnav = {
          slidesToShow: 3,
          swipeToSlide: true,
          arrows: false,
          dots: false,
          focusOnSelect: true,
        };

        return (
          <div>
            {/* <Breadcrumb title={" Product / " + item.name} /> */}

            {/*Section Start*/}
            {item ? (
              <section className="section-b-space">
                <div className="collection-wrapper">
                  <div className="container">
                    <div className="row">
                      <div className="col-lg-9 col-sm-12 col-xs-12">
                        <div className="container-fluid">
                          <div className="row">
                            <div className="col-xl-12">
                              <div className="filter-main-btn mb-2">
                                <span className="filter-btn">
                                  <i
                                    className="fa fa-filter"
                                    aria-hidden="true"
                                  ></i>{" "}
                                  filter
                                </span>
                              </div>
                            </div>
                          </div>
                          <div className="row">
                            <div className="col-lg-6 product-thumbnail">
                              <Slider
                                {...products}
                                asNavFor={this.state.nav2}
                                ref={(slider) => (this.slider1 = slider)}
                                className="product-slick"
                              >
                                {item.variants.map((vari, index) => (
                                  <div key={index}>
                                    <ImageZoom
                                      image={vari.images}
                                      className="img-fluid image_zoom_cls-0"
                                    />
                                  </div>
                                ))}
                              </Slider>
                              <SmallImages
                                item={item}
                                settings={productsnav}
                                navOne={this.state.nav1}
                              />
                            </div>
                            <DetailsWithPrice
                              symbol={symbol}
                              item={item}
                              navOne={this.state.nav1}
                              addToCartClicked={addToCart}
                              BuynowClicked={addToCartUnsafe}
                              addToWishlistClicked={addToWishlist}
                            />
                          </div>
                        </div>
                        <DetailsTopTabs item={item} />
                      </div>
                      <div className="col-sm-3 collection-filter">
                        {/* <BrandBlock/> */}
                        <Service />
                        {/*side-bar single product slider start*/}
                        <NewProduct />
                        {/*side-bar single product slider end*/}
                      </div>
                    </div>
                  </div>
                </div>
              </section>
            ) : (
              ""
            )}
            {/*Section End*/}
          </div>
        );
      }
    }

    const mapStateToProps = (state, ownProps) => {
      let productId = ownProps.match.params.id;
      return {
        item: state.data.products.find((el) => el.id == productId),
        symbol: state.data.symbol,
      };
    };

    export default connect(mapStateToProps, {
      addToCart,
      addToCartUnsafe,
      addToWishlist,
    })(RightSideBar);
}

Please try to update to your render method with this请尝试使用此更新您的渲染方法


render() {
        const {
          symbol,
          item,
          addToCart,
          addToCartUnsafe,
          addToWishlist,
        } = this.props;
        console.log(item.name);
        var products = {
          slidesToShow: 1,
          slidesToScroll: 1,
          dots: false,
          arrows: true,
          fade: true,
        };
        var productsnav = {
          slidesToShow: 3,
          swipeToSlide: true,
          arrows: false,
          dots: false,
          focusOnSelect: true,
        };

let productVariants = [];
        if(item && item.variants && Array.isArray(item.variants) && item.variants.length > 0)
           productVariants = item.variants.map((vari, index) => (
                                  <div key={index}>
                                    <ImageZoom
                                      image={vari.images}
                                      className="img-fluid image_zoom_cls-0"
                                    />
                                  </div>
                                ))}

        return (
          <div>
            {/* <Breadcrumb title={" Product / " + item.name} /> */}

            {/*Section Start*/}
            {item ? (
              <section className="section-b-space">
                <div className="collection-wrapper">
                  <div className="container">
                    <div className="row">
                      <div className="col-lg-9 col-sm-12 col-xs-12">
                        <div className="container-fluid">
                          <div className="row">
                            <div className="col-xl-12">
                              <div className="filter-main-btn mb-2">
                                <span className="filter-btn">
                                  <i
                                    className="fa fa-filter"
                                    aria-hidden="true"
                                  ></i>{" "}
                                  filter
                                </span>
                              </div>
                            </div>
                          </div>
                          <div className="row">
                            <div className="col-lg-6 product-thumbnail">
                              <Slider
                                {...products}
                                asNavFor={this.state.nav2}
                                ref={(slider) => (this.slider1 = slider)}
                                className="product-slick"
                              >
                                {productVariants}
                              </Slider>
                              <SmallImages
                                item={item}
                                settings={productsnav}
                                navOne={this.state.nav1}
                              />
                            </div>
                            <DetailsWithPrice
                              symbol={symbol}
                              item={item}
                              navOne={this.state.nav1}
                              addToCartClicked={addToCart}
                              BuynowClicked={addToCartUnsafe}
                              addToWishlistClicked={addToWishlist}
                            />
                          </div>
                        </div>
                        <DetailsTopTabs item={item} />
                      </div>
                      <div className="col-sm-3 collection-filter">
                        {/* <BrandBlock/> */}
                        <Service />
                        {/*side-bar single product slider start*/}
                        <NewProduct />
                        {/*side-bar single product slider end*/}
                      </div>
                    </div>
                  </div>
                </div>
              </section>
            ) : (
              ""
            )}
            {/*Section End*/}
          </div>
        );
      }



声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM