Reputation: 37
I am trying to use the useEffect to grab some data from an API. I am succesful in grabbing the data but after I set my state and try to map through it I just get "Can't read map of undefined". I think the problem is that it's running my .map() code before it gets the response. i am just unsure of how to solve this
This is the api response:
data: {count: 87, next: "https://swapi.co/api/people/?page=2", previous: null, results: Array(10)}
Here is my code
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
import CharacterMap from './characterMap'
const App = () => {
let [getChars, setChars] = useState(0);
useEffect(() => {
axios.get(`https://swapi.co/api/people/`)
.then(res => setChars(res) )
},[]);
console.log(getChars.data.map((e) => e))
return (
<div className="App">
<CharacterMap info={getChars} />
</div>
);
}
export default App;
Upvotes: 4
Views: 23554
Reputation: 9769
you are setting data to array chars
. instead of that set array(results
) that you are getting in response.
As you defined let [getChars, setChars] = useState([]);
useEffect(() => {
function getData() {
axios
.get(`https://swapi.co/api/people/`)
.then(res=> setChars(res.data.results))
.catch(err=> console.log(err))
}
getData();
},[]);
Upvotes: -1
Reputation: 10579
axios.get
is an async function and you are trying to get the data outside of an async function which is no completed yet.
You could use useEffect
with dependency array which is equal to componentDidUpdate
to get the data.
Initialized the state with the same datatype that you expect, in this case we expect an array you initialized ith with empty array.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
import CharacterMap from './characterMap'
const App = () => {
let [chars, setChars] = useState([]);
useEffect(async () => {
try{
let response = await axios.get(`https://swapi.co/api/people/`)
let data = await response.json();
setChars(data);
} catch(error) {
console.error(error.message);
}
},[]);
// If you want to access the updated state then use this.
useEffect(() => {
let newState = chars.map((e) => e); // map your state here
setChars(newState); // and then update the state
console.log(newState);
},[getChars]);
return (
<div className="App">
<CharacterMap info={chars} />
</div>
);
}
export default App;
The second useEffect
hook trigger on each state
update and so you can get the updated state
here.
It will also trigger a re-render
so you can also use the map
in return statement;
Or you could update the data on axios
response and then set the state
. Recommended
useEffect(async () => {
try{
let response = await axios.get(`https://swapi.co/api/people/`)
let data = await response.json();
let newState = data.map((e) => e); // map your state here
setChars(newState); // and then update the state
console.log(newState);
} catch(error) {
console.error(error.message);
}
},[]);
Upvotes: 5
Reputation: 11001
Keep the default values as array
let [getChars, setChars] = useState([]);
Upvotes: 1