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

(React 和 Redux) 添加商品到购物车的问题

如何解决(React 和 Redux) 添加商品到购物车的问题

我正在学习一个教程,我们正在构建一个购物车,该教程仍未完成,但我想在继续教程之前解决这个问题。

问题是,当我尝试将任何商品添加到购物车时,购物车仍在提示我,我的购物车是空的。您可以在下面这张图片的 url 中注意到,我已将 ID 编号为 1 的商品添加到购物车中,并且数量 (qty) 也是 1。

enter image description here

但购物车在添加商品后不应响应此类消息。在代码所在的这个阶段,响应应该只是一个空白页面

当我尝试对购物车项目进行控制台记录时,这还不起作用 - 它对我来说是一个空数组,但讲师正在接收有关产品的数据,这些数据已添加到购物车中。所以这可能是一个线索。

请查看以下文件,如果您能看到任何提示解决方案,请告诉我。

CartScreen.js -

import React,{useEffect} from 'react'
import { Link } from 'react-router-dom'
import { usedispatch,useSelector } from 'react-redux'
import { Row,Col,ListGroup,Image,Form,Button,Card } from 'react-bootstrap'
import Message from '../components/Message'
import { addToCart } from '../actions/cartActions'


function CartScreen({ match,location,history }) {
    const productId = match.params.div
    const qty = location.search ? Number(location.search.split('=')[1]) : 1
    
    const dispatch = usedispatch()

    const cart = useSelector(state => state.cart)
    const { cartItems } = cart
    
    useEffect(() =>{
        if(productId){
            dispatch(addToCart(productId,qty))
        }    
    },[dispatch,productId,qty])
    return (
        <Row>
            <Col md={8}>
             <h1>Shopping Cart</h1>
             {cartItems.length === 0 ? (
                 <Message variant='info'>
                     Your cart is empty <Link to='/'>Go Back</Link>
                 </Message>
             ) : (
                 <listGroup variant='flush'>

                 </listGroup>
             )}
            </Col>

            <Col md={4}>
                
            </Col>
        </Row>
    )
}

export default CartScreen

cartActions.js -

import axios from 'axios'
import { CART_ADD_ITEM } from '../constants/cartConstants'

export const addToCart = (id,qty) => async (dispatch,getState) => {
   const { data } = await axios.get(`/api/products/${id}`)

   dispatch({
      type:CART_ADD_ITEM,payload:{
          product:data._id,name:data.name,image:data.image,price:data.price,countInStock:data.countInStock,qty
    }
   })
   localStorage.setItem('cartItems',JSON.stringify(getState().cart.cartItems))
}

cartReducers.js -

import { CART_ADD_ITEM } from '../constants/cartConstants'

export const cartReducer = (state={cartItems:[] },action) => {
   switch (action.type) {
       case CART_ADD_ITEM:
           const item = action.payload
           const existItem = state.cartItems.find(x => x.product === item.product)
           
           if(existItem){
               return{
                   ...state,cartItems: state.cartItems.map(x =>
                     x.product === existItem.product ? item : x)
               }
           }else{
              return{
                  ...state,cartItems:[...state.cartItems,item]
              }
           }
       default:
           return state
    }
}

cartConstants.js -

export const CART_ADD_ITEM = 'CART_ADD_ITEM'
export const CART_REMOVE_ITEM = 'CART_REMOVE_ITEM'

store.js -

import { createStore,combineReducers,applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension'
import { productListReducer,productDetailsReducer } from './reducers/productReducers'
import { cartReducer } from './reducers/cartReducers'

const reducer = combineReducers({
    productList:productListReducer,productDetails:productDetailsReducer,cart: cartReducer,})

const cartItemsFromStorage = localStorage.getItem('cartItems') ?
        JSON.parse(localStorage.getItem('cartItems')) : []

const initialState = {
    cart: { cartItems: cartItemsFromStorage }
}

const middleware = [thunk]

const store = createStore(reducer,initialState,composeWithDevTools(applyMiddleware(...middleware)))

export default store

ProductScreen.js -

import React,{ useState,useEffect } from "react";
import { usedispatch,useSelector } from 'react-redux'
import { Link } from "react-router-dom";
import { Row,Card,Form } from "react-bootstrap";
import rating from "../components/rating";
import Loader from "../components/Loader";
import Message from "../components/Message";
import { listProductDetails } from '../actions/productActions'

function ProductScreen({ match,history }) {
  const[qty,setQty] = useState(1)

  const dispatch = usedispatch()
  const productDetails = useSelector(state => state.productDetails)
  const { loading,error,product } = productDetails
 
  useEffect(() => {
     dispatch(listProductDetails(match.params.id))
  },match])

  const addToCartHandler = () => {
    history.push(`/cart/${match.params.id}?qty=${qty}`)
  }

  return (
    <div>
      <Link to="/" className="btn btn-light my-3">
        Go Back
      </Link>
      {loading ?
         <Loader/>
         : error
             ? <Message variant='danger'>{error}</Message>
         :(
          <Row>
          <Col md={6}>
            <Image src={product.image} alt={product.name} fluid />
          </Col>
  
          <Col md={3}>
            <ListGroup variant="flush">
              <ListGroup.Item>
                <h3>{product.name}</h3>
              </ListGroup.Item>
  
              <ListGroup.Item>
                <rating
                  value={product.rating}
                  text={`${product.numReviews} reviews`}
                  color={"#f8e825"}
                />
              </ListGroup.Item>
  
              <ListGroup.Item>Price: ${product.price}</ListGroup.Item>
  
              <ListGroup.Item>Description: {product.description}</ListGroup.Item>
            </ListGroup>
          </Col>
  
          <Col md={3}>
            <Card>
              <ListGroup variant="flush">
                <ListGroup.Item>
                  <Row>
                    <Col>Price:</Col>
                    <Col>
                      <strong>${product.price}</strong>
                    </Col>
                  </Row>
                </ListGroup.Item>
  
                <ListGroup.Item>
                  <Row>
                    <Col>Status:</Col>
                    <Col>
                      {product.countInStock > 0 ? "In Stock" : "Out of Stock"}
                    </Col>
                  </Row>
                </ListGroup.Item>

                {product.countInStock > 0 && (
                  <ListGroup.Item>
                    <Row>
                      <Col>Qty</Col>
                      <Col xs='auto' className='my-1'>
                        <Form.Control
                          as="select"
                          value={qty}
                          onChange={(e) => setQty(e.target.value)}
                        >
                          {
                          
                            [...Array(product.countInStock).keys()].map((x) => (
                              <option key={x + 1} value={x + 1}>
                                {x + 1}
                              </option>
                            ))
                          }

                        </Form.Control>
                      </Col>
                    </Row>
                  </ListGroup.Item>
                )}


  
                <ListGroup.Item>
                  <Button
                    onClick={addToCartHandler}
                    className="btn-block"
                    disabled={product.countInStock == 0}
                    type="button"
                  >
                    Add to Cart
                  </Button>
                </ListGroup.Item>
              </ListGroup>
            </Card>
          </Col>
        </Row>
         )

      }

      
    </div>
  );
}

export default ProductScreen;

解决方法

这里是错误:

const productId = match.params.div

应该是“id”而不是div

const productId = match.params.id
,

在cartReducers.js 中更新状态时使用state.cartItems,在CartScreen.js 中使用const cart = useSelector(state => state.cart)

我看不到 index.js,但看起来您的州名可能不一致。建议:useSelector(state => state.cartItems)

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

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?