Не обработанный отказ (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 кажется нормальным. Пожалуйста, очистите ваше локальное хранилище и попробуйте снова. Если вы не знаете, как это сделать, удалите данные браузера или следуйте руководству здесь .