Search code examples
reactjsreduxreact-reduxreact-hooksuse-effect

List of products did not display


I got:

store.js

import {productListReducer,productDetailsReducer,} from './reducers/productReducers'
const reducer = combineReducers({ productList: productListReducer, productDetails: productDetailsReducer,})

const initialState = {}
const middleware = [thunk]
const store = createStore(
  reducer,
  initialState,
  composeWithDevTools(applyMiddleware(...middleware))
)

export default store

productListReducer.js

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,
        pages: action.payload.pages,
        page: action.payload.page,
      }
    case PRODUCT_LIST_FAIL:
      return { loading: false, error: action.payload }
    default:
      return state
  }
}

productActions.js

export const listProducts = (keyword = '', pageNumber = '') => async (
  dispatch
) => {
  try {
    dispatch({ type: PRODUCT_LIST_REQUEST })

    const { data } = await axios.get(
      `/api/products?keyword=${keyword}&pageNumber=${pageNumber}`
    )

    console.log(data) //data has items

    dispatch({
      type: PRODUCT_LIST_SUCCESS,
      payload: data,
    })
  } catch (error) {
    dispatch({
      type: PRODUCT_LIST_FAIL,
      payload:
        error.response && error.response.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}

HomeScreen.js

import { listProducts } from '../action/productActions'

const HomeScreen = ({match}) => {

  const keyword = match.params.keyword
  const pageNumber = match.params.pageNumber || 1
  const dispatch = useDispatch()

  const productList = useSelector((state) => state.productList)
  const { loading, error, products, page, pages } = productList

  useEffect(() => {
    dispatch(listProducts(keyword, pageNumber))

    console.log(productList) //empty
    console.log(products) //empty

  }, [dispatch, keyword, pageNumber])

I see that my data is fetching ok (productActions.js), but then I don't see any products into HomeScreen.js

--Added HomeScreen.js => return

  return (
    <>
      <h1>Latest Products</h1>
      {loading ? (
        <Loader />
      ) : error ? (
        <Message variant='danger'>{error}</Message>
      ) : (
        <>
          <Row>
            {products > 0 && products.map((product) => (
              <Col key={product._id} sm={12} md={6} lg={4} xl={3}>
                <Product product={product} />
              </Col>
            ))}
          </Row>
        </>
      )}
    </>
  )

--Update => index.js

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

---Redux Into PRODUCT_LIST_SUCCESS I see that payload has data, somehow it's not passed...

sometimes also is showing this: GET http://localhost:3000/api/products 500 (Internal Server Error)

---Log from PRODUCT_LIST_REQUEST & PRODUCT_LIST_SUCCESS

-action-

enter image description here

-state-

enter image description here

===Dev tools / Network

When I see Network tab its as below: enter image description here

also, into tab "Response" I see my data

--preview enter image description here

--response enter image description here


Solution

  • With little help I resolved my issue. So issue was into "productReducers.js", where I tried to pass products: action.payload.products, which was wrong. Should be just products: action.payload

    Here is correct code:

    case PRODUCT_LIST_SUCCESS:
          return {
            loading: false,
            products: action.payload
          }