javascript - react redux 中的数据映射有问题吗?
问题描述
我们目前正在使用 react-redux 构建一个电子商务网站。我们使用模拟 JSON 数据来使用 JSON-server 开发产品和类别页面。但是在用真实数据改变数据的同时。那么我们遇到了 typeError 的问题:item.variant 是未定义的。
任何人都可以帮助解决这个问题。
模拟数据:
{
"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"
}
]
}
]
真实数据:
{
"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": []
}
]
}
零件:
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);
}
解决方案
请尝试使用此更新您的渲染方法
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>
);
}
推荐阅读
- .net - 有哪些选项可以在 .Net 中使用具有负面后视功能的可变长度捕获组?
- c# - 等待 C# 中 lambda 函数的结果
- sql - 使用 spark 或 scala 删除具有十亿条记录的表中的记录
- passport.js - 使用passportJS从instagram检索accessToken失败
- c# - 使用 Active Directory 对用户进行身份验证,而不在 catch 块内放置不正确的用户名或密码错误
- css - 如何通过css正确创建一个简单的圆形进度条
- quarkus - 有没有办法将 bean 注册到 maven 子模块中?
- sql - 如何连接 1 个表中的列。一列用逗号分隔
- java - 如何获取场景的新坐标
- asp.net - 如何修复 vb 中 dbcontext 上的空引用错误?