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.