#javascript #node.js #reactjs #redux #mern
Вопрос:
Как решить эту проблему? Я прикрепил все соответствующие фрагменты кода здесь. Когда я пытаюсь отобразить продукты на главном экране, я получаю эту ошибку, когда я открываю этот проект, он показывает загрузку в течение нескольких секунд, а затем показывает эту ошибку. Что нужно сделать для исправления этой ошибки?
import React, { useEffect} from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Row, Col } from 'react-bootstrap'
import Product from '../components/Product'
import { listProducts } from '../actions/productActions.js'
import Message from '../components/Message'
import Loader from '../components/Loader'
const HomeScreen = () => {
const dispatch = useDispatch()
const productList = useSelector((state) => state.productList);
const { loading, error, products} = productList;
useEffect(() => {
dispatch(listProducts())
}, [dispatch])
return (
<>
<h1>All Products</h1>
{loading ? (
<Loader />
) : error ? (
<Message variant='danger'>{error}</ Message>
) : (
<Row>
{products.map((product) => (
<Col sm={12} md={6} lg={4} xl={3} key={product._id}>
<Product product={product} />
</Col>
))}
</Row>
)}
</>
)
}
export default HomeScreen
А вот страница productAction в redux
import {PRODUCT_LIST_REQUEST, PRODUCT_LIST_SUCCESS, PRODUCT_LIST_FAIL,
PRODUCT_DETAILS_REQUEST, PRODUCT_DETAILS_SUCCESS, PRODUCT_DETAILS_FAIL} from '../constants/productConstants'
import axios from 'axios'
export const listProducts = () => async (dispatch) => {
try {
dispatch({ type: PRODUCT_LIST_REQUEST })
const {data} = await axios.get('/api/products')
dispatch({
type: PRODUCT_LIST_SUCCESS,
payload: data
})
} catch (error) {
dispatch({
type: PRODUCT_LIST_FAIL,
payload:
error.response amp;amp; error.response.data.message
? error.response.data.message
: error.message
})
}
}
export const listProductDetails = (id) => async (dispatch) => {
try {
dispatch({ type: PRODUCT_DETAILS_REQUEST })
const { data } = await axios.get(`/api/products/${id}`)
dispatch({
type: PRODUCT_DETAILS_SUCCESS,
payload: data,
})
} catch (error) {
dispatch({
type: PRODUCT_DETAILS_FAIL,
payload:
error.response amp;amp; error.response.data.message
? error.response.data.message
: error.message,
})
}
}
Страница производителей продукции:
import {PRODUCT_LIST_REQUEST, PRODUCT_LIST_SUCCESS, PRODUCT_LIST_FAIL,
PRODUCT_DETAILS_REQUEST, PRODUCT_DETAILS_SUCCESS, PRODUCT_DETAILS_FAIL} from '../constants/productConstants'
export const productListReducer = (state = { products: []}, action ) => {
switch( action.type ) {
case PRODUCT_LIST_REQUEST:
return { loading: true, products: []}
case PRODUCT_LIST_SUCCESS:
return { loading: false, products: action.payload}
case PRODUCT_LIST_FAIL:
return { loading: false, error: action.payload}
default:
return state
}
}
export const productDetailsReducer = (
state = { product: { reviews: [] } },
action
) => {
switch (action.type) {
case PRODUCT_DETAILS_REQUEST:
return { loading: true, ...state }
case PRODUCT_DETAILS_SUCCESS:
return { loading: false, product: action.payload }
case PRODUCT_DETAILS_FAIL:
return { loading: false, error: action.payload }
default:
return state
}
}
Комментарии:
1. Вы проверили данные ответа? Это массив ?
2. Можете ли вы показать часть редуктора?
3. @AbinThaha это добавлено сейчас.
4. @AzizulTareq отладьте в точке состояния и проверьте, что вы получаете в состоянии, я думаю,
productList
здесь проблема в том, что ключ
Ответ №1:
- Сначала посмотрите, правильно ли работает ваш API.
- Если он работает правильно, и даже тогда у вас возникает эта ошибка, то проблема заключается в том, как вы обновляете свой магазин redux. Здесь продукты-это элемент из списка продуктов. Вы меняете свойство объекта, но сам объект, похоже, не меняется с точки зрения реакции.
Проверьте свою логику редуктора, и если вы обновляете значение хранилища, сделайте это так
initialState = { loading, error, products: [] }
......
......
return {
...state,
products: [...fetched products]
}
эти 3 точки (…) гарантируют, что вы создадите новый объект. В redux вы всегда должны создавать новый объект, а не просто обновлять состояние.
- При использовании переменных всегда сначала убедитесь, что переменная и ее свойство, которые вы хотите использовать, существуют. В вашем случае вы напрямую используете products.map, и это нарушает интерфейс. Сначала проверьте, действительно ли продукты являются списком или нет, а затем используйте products.map. Таким образом, ваш интерфейс не сломается, даже если стоимость продуктов не определена.
Ответ №2:
Я решил эту проблему, добавив action.payload.products
на страницу productReducers. Исправленный код находится здесь:
export const productListReducer = (state = { products: []}, action ) => {
switch( action.type ) {
case PRODUCT_LIST_REQUEST:
return { loading: true, products: []}
case PRODUCT_LIST_SUCCESS:
return { loading: false, products: action.payload.products}
case PRODUCT_LIST_FAIL:
return { loading: false, error: action.payload}
default:
return state
}
}