javascript - 映射通过 Redux 连接的产品但它们不显示?
问题描述
如果您跳到 26 分钟,我将在此处关注本教程,这是我正在关注的部分,通过映射它们来渲染通过 redux 连接的产品。
我没有错误,我的代码与教程相同,我最初是通过道具将我的产品渲染到卡片上,但是我试图实现与本教程相同的结构,因为以前当我遵循教程并将其应用于我现有的项目时我无法让 redux 实际将产品添加到我的购物车中,所以我只是尝试按照教程显示的方式进行操作,看看这是否解决了问题……请参阅我的旧问题的帖子。
当我 console.log(prod) 显示产品及其所有数据时,我不知道为什么它不呈现它们。
下面的代码:MyMenu.js
import { Col, Row } from 'antd';
import React from 'react'
import Cardo from './Card';
import data from '../Data/MenuData';
import { connect } from 'react-redux';
import shopReducer from '../Redux/Shopping/ShoppingReducer';
import ReduxCardo from './ReduxRenderedCard';
// const cardCreator = (props) => {
// return(
// <Col span={{xs: 24, sm: 12, md: 8, lg: 6}}>
// <Cardo
// key={props.id}
// image={props.image}
// header={props.header}
// price={props.price}
// description={props.description}
// />
// </Col>
// )
// }
function MyMenu({ products }) {
return (
<div className="menu">
<h1 className="menu-header" >Starters</h1>
<hr className="menu-divider"/>
<Row className="menu-row" gutter={{xs: 32, sm: 24, md: 16, lg: 8}}>
{/* {products.slice(0,4).map(cardCreator)} */}
{products.map((prod) => {
<ReduxCardo key={prod.id} productData={prod} />
console.log(prod);
})}
</Row>
<h1 className="menu-header">Mains</h1>
<hr className="menu-divider"/>
<Row className="menu-row" gutter={{xs: 32, sm: 24, md: 16, lg: 8}}>
{/* {products.slice(4, 12).map(cardCreator)} */}
</Row>
<h1 className="menu-header">Rice</h1>
<hr className="menu-divider"/>
<Row className="menu-row" gutter={{xs: 32, sm: 24, md: 16, lg: 8}}>
{/* {products.slice(12,14).map(cardCreator)} */}
</Row>
<h1 className="menu-header">Desserts</h1>
<hr className="menu-divider"/>
<Row className="menu-row" gutter={{xs: 24, sm: 12, md: 8, lg: 6}}>
{/* {products.slice(14,18).map(cardCreator)} */}
</Row>
</div>
)
}
const mapStateToProps = (state) => {
return{
products: state.shop.products,
};
}
export default connect(mapStateToProps)(MyMenu);
ReduxRenderedCard.js
import React, {useState} from 'react';
import 'antd/dist/antd.css';
import { Card, Avatar, Button, Modal } from 'antd';
import { EditOutlined, EllipsisOutlined, PlusCircleTwoTone, SettingOutlined } from '@ant-design/icons';
import {connect} from 'react-redux';
import {addToCart} from '../Redux/Shopping/ShoppingActions'
const { Meta } = Card;
function ReduxCardo({productData, addToCart}) {
//Setting variables up to use for useState so to manage state of modal
//Default state is false so not to be visible
const [isModalVisible, setIsModalVisible] = useState(false);
const showModal = () => {
setIsModalVisible(true);
};
const handleOk = () => {
setIsModalVisible(false);
};
const handleCancel = () => {
setIsModalVisible(false);
};
//^^^All the const's above will be called below within the card or modal to manage the state of the modal
return (
<div className="card">
<Card
style={{ width: "340px", textAlign: 'center' }}
cover={<img className="card-cover" src={productData.image}/>}
actions={[
// <SettingOutlined key="setting" />,
// <EditOutlined onClick={showModal} key="edit" />,
<EllipsisOutlined onClick={showModal} key="ellipsis" />,
]}
>
<Meta
avatar={<Button className="card-button" onClick={() => addToCart(productData.id)} type="primary" shape="circle"><PlusCircleTwoTone /></Button>}
title={productData.header}
description={productData.price}
/>
</Card>
<Modal title={productData.header} visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<p>{productData.description}</p>
</Modal>
</div>
)
}
const mapDispatchToProps = (dispatch) => {
return{
addToCart: (id) => dispatch(addToCart(id)),
}
}
export default connect(null, mapDispatchToProps)(ReduxCardo);
减速器代码和数据文件如下。
ShoppingReducer.js
import * as actionTypes from './ShoppingTypes';
import data from '../../Data/MenuData';
const INITIAL_STATE = {
products: data,//(id, title, description, price, img)
cart: [], //(id, title, description, price, img, qty)
currentItem: null,
}
//reducer is just function that takes in state and action - action is part that gets dispatched which contains a type
const shopReducer = (state = INITIAL_STATE, action) => {
switch(action.type){
case actionTypes.ADD_TO_CART:
//get items data from products array
const item = state.products.find((product) => product.id === action.payload.id);
//we need to check if item is in cart already
const inCart = state.cart.find((item) => item.id === action.payload.id ? true : false);
// console.log(action.payload.id)
return{
//we spread the state first so not to lose current or all the products
...state,
//inCart we check if it is in cart and that return true - if so map through cart and find that id
cart: inCart ? state.cart.map((item) =>
item.id === action.payload.id
//Then spread all of data inside and change quantity if needed
? {...item, qty: item.qty + 1} : item
) //if not in cart then spread the array and add the item and quantity to state of cart
: [...state.cart, { ...item, qty: 1}],
};
case actionTypes.REMOVE_FROM_CART:
return{
...state,
//this filters through array and deletes item we want to remove
cart: state.cart.filter(item => item.id !== action.payload.id)
};
case actionTypes.ADJUST_QTY:
return{
...state,
//if i find id in cart I want to recreate object by spreading current item and setting qty set to original qty - else return item
cart: state.cart.map((item) => item.id === action.payload.id ? {...item, qty: action.payload.qty} : item)
};
case actionTypes.LOAD_CURRENT_ITEM:
return{
...state,
currentItem: action.payload,
};
default:
return state;
}
}
export default shopReducer;
菜单数据.js
const data = [
{
id: 1,
image: 'https://d3lp4xedbqa8a5.cloudfront.net/s3/digital-cougar-assets/food/2014/11/28/WomansDayBR109894/steamed-beef-dumplings.jpg?width=600&height=315&quality=75&mode=crop',
header: "Meat Dumplings",
price: 4.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 2,
image: 'https://pixel.parall.ax/parallax-agency/image/upload/w_560,h_575,c_fill/expose/cauldron-2018/images/49265d45f7_2018-12-19-12-21-27_1600_1067.jpg',
header: "Veggie Dumplings",
price: 3.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 3,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Duck Spring Rolls",
price: 4.29,
// amount: 1,
description: 'Some Description here....'
},
{
id: 4,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Veggie Spring Rolls",
price: 3.79,
// amount: 1,
description: 'Some Description here....'
},
{
id: 5,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Green Thai Curry",
price: 9.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 6,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Red Thai Curry",
price: 9.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 7,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Pad Thai",
price: 12.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 8,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Japanese Curry",
price: 10.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 9,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Spicy Sichuan Tofu Noodles",
price: 8.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 10,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Tonkotsu Ramen",
price: 12.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 11,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Spicy Miso Noodles",
price: 7.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 12,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Oyaka Don",
price: 8.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 13,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Matcha Brownies",
price: 4.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 14,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Salted Caramel Brownies",
price: 3.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 15,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Jasmine Rice",
price: 2.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 16,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Sticky Japanese Rice",
price: 3.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 17,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Basmati Rice",
price: 1.99,
// amount: 1,
description: 'Some Description here....'
},
{
id: 18,
image: 'https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
header: "Egg Fried Rice",
price: 3.99,
// amount: 1,
description: 'Some Description here....'
},
]
export default data;
解决方案
推荐阅读
- laravel - 在 Laravel 应用程序中是否有指定的位置来存储帮助脚本?
- java - 如何使用 spring-data-elasticsearch 存储 java 枚举
- .net - Powershell 中的椭圆曲线秘密值推导原语 (ECSVDP-DH)
- java - 如何配置一尘不染的谷歌格式化程序来格式化大括号
- android - 如何从firebase实时数据库中的不同孩子获取值?
- html - 设计在不同的屏幕中破碎
- mysql - 如何使用 Google Cloud SQL 实例授权 circle-ci
- laravel - Laravel Voyager 管理面板(小编辑器)
- python - django中的整数错误(我认为它与那个新的外键有关)
- android - 为什么很多安卓应用的闪屏在点击返回键的时候没有关闭?