简体   繁体   中英

TypeError: Cannot read property 'map' of undefined in react-redux Array API

Hello I'm having a problem with React.js REDUX

Can you please help me?

What I'm trying to get : I want to display an api into a list on my component

Issue : Uncaught TypeError: Cannot read properties of undefined (reading 'map')and Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'map')

this is the reducer:

import { ActionTypes } from "../contants/action-types";
const intialState = {
  products: [],
};

export const productReducer = (state = intialState, { type, payload }) => {
  switch (type) {
    case ActionTypes.SET_PRODUCTS:
      return { ...state, products: payload };
    default:
      return state;
  }
};

export const selectedProductsReducer = (state = {}, { type, payload }) => {
  console.log(type);
  switch (type) {
    case ActionTypes.SELECTED_PRODUCT:
      return { ...state, ...payload };
    case ActionTypes.REMOVE_SELECTED_PRODUCT:
      return {};
    default:
      return state;
  }
};

Main.js

import React, {useEffect} from 'react';
import axios from "axios";
import { useDispatch, useSelector } from 'react-redux';
import {setProducts} from "../../redux/actions/productActions";
import MarsRoversListing from './MarsRoversListing';

const MarsRovers = () => {

  const products = useSelector((state) => state);
  const dispatch = useDispatch();

  const fetchProducts = async () => {
    const response = await axios
    .get("https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1000&camera=fhaz&api_key=DEMO_KEY")
    .catch((err) => {
      console.log("Err", err);
    });
    dispatch(setProducts(response.data.data));
  };

  useEffect(() => {
    fetchProducts();
  }, []);
  console.log("Products: ", products)

  return (
    <div className='grid container'>
        <MarsRoversListing />
    </div>
  )
}

export default MarsRovers
List.js

import React from 'react';
import { useSelector } from "react-redux";

const MarsRoversListing = () => {

    const products = useSelector((state) => state.allProducts.products);
    const renderList = products.map((product) => {
        const {id, title, url, date, hdurl, copyright, explanation} = product;
        return (<div className="four columns wide" key={id}>
            <div className="ui">
                <div className="card">
                    <div className="image">
                        <img src={url} alt= {explanation} />
                        <div className="content">
                            <div className="header">{title}</div>
                            <div className="header">{hdurl}</div>
                            <div className='rover-name'>{copyright}</div>
                            <div className='date'>{date}</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>);
    })

    return (
        <>
        {renderList}
        </>
  )
}

export default MarsRoversListing

I would confirm products exists before trying to map it. Also no need for a renderList variable, you can map it directly in the return statement. Additionally I recommend you put text in <p> elements to be more semantically correct. Ex:

const MarsRoversListing = () => {

    const products = useSelector((state) => state.allProducts.products);
    return ( 
      products && products.map((product) => {
        return (
          <div className="four columns wide" key={product?.id}>
            <div className="ui">
                <div className="card">
                    <div className="image">
                        <img src={product?.url} alt={product?.explanation}/>
                        <div className="content">
                            <p className="header">{product?.title}</p>
                            <p className="header">{product?.hdurl}</p>
                            <p className='rover-name'>{product?.copyright</p>
                            <p className='date'>{product?.date}</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>);
    })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM