Не обработанный отказ (TypeError): Невозможно прочитать свойства null (чтение 'product')

Эта ошибка появляется у меня, когда я добавляю что-то в корзину. Я проверял код много раз, но я все еще не могу найти решение, я не знаю, как заставить его работать.

код в 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))
}   

код в cardReducers.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;

    }



}


код в CartScreen.js

import React, {useEffect} from 'react'
import { useParams, useLocation } 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() {
  const {prodId} = useParams()
  const location = useLocation()
  const qty = location.search ? Number(location.search.split('=')[1]) : 1
  
  const dispatch = useDispatch()

  const cart = useSelector(state => state.cart)
  const { cartItems } = cart

  
  useEffect(() => {
    if (prodId) {
      dispatch(addToCart (prodId, qty))
    }
      
      
  }, [dispatch, prodId, qty])

  return(
    <div>
      Cart
    </div>
  )

};

export default CartScreen  


Здесь я прикрепил изображение с ошибкой

введите описание изображения здесь

x является null, поэтому вы не можете получить доступ к свойству product на нем. Просто используйте здесь необязательную цепочку или добавьте проверку if. Это должно исправить ошибку:

const existItem = state.cartItems.find(x => x?.product === item.product)

Но не знаю, почему элемент вообще равен null, возможно, вам стоит сначала выяснить это.

вот измененный код, как вы мне сказали, но у меня та же ошибка. извините за беспокойство, но мне действительно не у кого спросить. спасибо большое за вашу помощь

код cartReducer.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 => {
                if(x == null){
                    return false;
                }else{
                    return 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;

    }



}



код cartScreen.js

import React, {useEffect} from 'react'
import { useParams, useLocation } 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() {
  const {prodId} = useParams()
  const location = useLocation()
  const qty = location.search ? Number(location.search.split('=')[1]) : 1
  
  const dispatch = useDispatch()

  const cart = useSelector(state => state.cart)
  const  {cartItems}  = cart
  console.log('cartItems:', cartItems)  
  
  useEffect(() => {
    if (prodId) {
      dispatch(addToCart (prodId, qty))
    }
      
      
  }, [dispatch, prodId, qty])

  return(
    <div>
      Cart
    </div>
  )

};

export default CartScreen

Это появляется, когда я обращаюсь к одному из продуктов и нажимаю на корзину, чтобы выбрать количество

введите описание изображения здесь

Это та же ошибка, только для метода map в строке 24. Поэтому все, что вам нужно сделать, это добавить еще один оператор if для проверки того, является ли x нулевым или неопределенным, как описано выше.

Это должно выглядеть следующим образом:

return {
    ...state,
    cartItems: state.cartItems.map(x => {
      if (x != null) {
        return x.product === existItem.product ? item : x
      } else {
        return x
      }
    })
}

или с необязательной цепочкой:

return{
    ...state,
    cartItems: state.cartItems.map(x => x?.product === existItem.product ? item : x)
}

Я все еще задаюсь вопросом, почему ваш первый элемент равен null. Может быть, вы инициализировали магазин этим значением?

я проверил все файлы и действительно не понимаю, почему первый продукт является нулевым

Теперь я заметил, что любой товар, который я кладу в корзину, распознает только первый. Насколько я понимаю, если я добавляю товар с id 3, т.е. третий товар из магазина в консоли, то выбирается товар с id 1, а не с id 3

введите описание изображения здесь

модифицированный код, как вы сказали

код в 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 => {
                if(x == null){
                    return false;
                }else{
                    return x.product === item.product;
                }


            })

            if(existItem){
                return {
                    ...state,
                    cartItems: state.cartItems.map(x => {
                      if (x != null) {
                        return x.product === existItem.product ? item : x
                      } else {
                        return x
                      
                      }
                    })
                }


            }
        
        default:
            return state;

    }



}



это код из 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




Почему вы удалили оператор else? Конечно, он не будет работать, если вы опустите эту логику :D

Код внутри store.js кажется нормальным. Пожалуйста, очистите ваше локальное хранилище и попробуйте снова. Если вы не знаете, как это сделать, удалите данные браузера или следуйте руководству здесь .

Вернуться на верх