Cannot read properties of undefined (reading 'map')
·
Answer a question
I need your help. I'm trying to get API data through redux. I have everything I need: action_types, action_creators, reducer. When I try to draw data, I get an error: Cannot read properties of undefined (reading 'map').What is my mistake? Thank you very much. Here is my code
cartoons.js
import React, {useEffect} from "react";
import {useDispatch, useSelector} from "react-redux";
import {cartoons_are_loaded} from "../redux/action_creators";
export let Cartoons = () => {
let dispatch = useDispatch();
let cartoons = useSelector(({cartoon_reducer: {cartoons}}) => cartoons);
let fetchCartoons = async () => {
try {
let response = await fetch('https://api.sampleapis.com/cartoons/cartoons2D');
let json = await response.json();
console.log(json);
dispatch(cartoons_are_loaded(json.data))
} catch (e) {
console.log(e)
}
}
useEffect(() => {
if (!cartoons.length){
fetchCartoons();
}
},[])
return (<div>
{cartoons.map(el => <div key={el.id}>{el.title}</div>)}
</div>)
}
reducers.js
import {CARTOONS_ARE_LOADED} from "./action_types";
let initialState = {
cartoons: []
}
let cartoon_reducer = (state = initialState, action) => {
switch (action.type) {
case CARTOONS_ARE_LOADED: {
return {
...state,
cartoons: action.payload
}
}
default:
return state;
}
}
export default cartoon_reducer;
action_types.js
let CARTOONS_ARE_LOADED = 'CARTOONS_ARE_LOADED';
let DELETE_FAVOURITE_MOVIE = 'DELETE_FAVOURITE_MOVIE';
let ADD_FAVOURITE_CARTOON = 'ADD_FAVOURITE_MOVIE';
export {
CARTOONS_ARE_LOADED,
ADD_FAVOURITE_CARTOON,
DELETE_FAVOURITE_MOVIE
}
action_creators.js
import {
CARTOONS_ARE_LOADED,
} from "./action_types";
let cartoons_are_loaded = (payload) => ({type : CARTOONS_ARE_LOADED, payload});
export {
cartoons_are_loaded
}
all_reducers.js
import cartoon_reducer from "./reducers";
import {combineReducers} from "redux";
export let root_reducer = combineReducers({
cartoon_reducer
})
Answers
Issue
The JSON response is already an array.
let json = await response.json();
// 20210915235745 // https://api.sampleapis.com/cartoons/cartoons2D [ { "title": "Spongebob Squarepants", "year": 1999, "creator": [ "Stephen Hillenburg" ], "rating": "TV-Y", "genre": [ "Comedy", "Family" ], "runtime_in_minutes": 23, "episodes": 272, "image": "https://nick.mtvnimages.com/uri/mgid:arc:content:nick.com:9cd2df6e-63c7-43da-8bde-8d77af9169c7?quality=0.7", "id": 1 }, ... { "title": "The New Adventures of Winnie the Pooh", "year": 1988, "creator": [ "Karl Geurs", "Terence Harrison", "Ken Kessel" ], "rating": "TV-Y", "genre": [ "Adventure", "Comedy" ], "runtime_in_minutes": 30, "episodes": 50, "image": "https://m.media-amazon.com/images/M/MV5BZjFkZDkwYjktMmZkNi00ZTVkLWI5ZmItZWI2MmI1NjQ1Y2U0XkEyXkFqcGdeQXVyOTg4MDk3MTQ@._V1_SY1000_CR0,0,666,1000_AL_.jpg", "id": 23 } ]
There is no data property, or in other words, json.data is undefined, and thus, not mappable.
Solution
Just dispatch the action with the json JSON data value:
dispatch(cartoons_are_loaded(json))
Full code:
const fetchCartoons = async () => {
try {
let response = await fetch('https://api.sampleapis.com/cartoons/cartoons2D');
let json = await response.json();
console.log(json);
dispatch(cartoons_are_loaded(json)) // <-- pass just `json`
} catch (e) {
console.log(e)
}
}
Here's an example codesandbox using local state instead of redux:
更多推荐
所有评论(0)