I am trying to set a React state to an array of objects via an Axios get request. However, when I try to update the state, it shows up as an empty array.
I know for a fact that I am receiving the correct response from the API, so I think I am missing somethig when it comes to updating the state.
Here's my code:
const Home = () => {
const [movieTitle, setMovieTitle] = useState('');
const [searchResults, setSearchResults] = useState([]);
const handleChange = (e) => {
setMovieTitle(e.target.value);
};
const getMovieData = () => {
const apiKey = 'didntleakit';
const apiUrl = 'http://www.omdbapi.com/?apikey=' apiKey '&s=' movieTitle;
Axios.get(apiUrl)
.then((res) => {
setSearchResults(res.data.Search);
});
console.log(searchResults);
};
return(
<div>
<p>Home page</p>
<TextField defaultValue="Movie" onChange={(e) => handleChange(e)}/>
<button onClick={getMovieData}/>
</div>
);
};
CodePudding user response:
You cannot log the state variable right after setting it as setState
is async. You can log the updated state inside a useEffect
:
import {useEffect} from 'react'
useEffect(() => {
console.log(searchResults);
}, [searchResults])
CodePudding user response:
That's because you are logging searchResults
BEFORE data was retrieved. Axios.get() is an async function, to fix it, just put console.log right before returning JSX code:
console.log(searchResults);
return (<div>....</div>);
So when the data is retrieved from the endpoint, you will update searchResults which will re-render the component with updated state and log correct searchResults to the console.
CodePudding user response:
You can not log state just after setting it as it is async so log it in useEffect and pass state as dependency array.
Always try to use spread operator while setting state if it is object or array.
const Home = () => {
const [movieTitle, setMovieTitle] = useState('');
const [searchResults, setSearchResults] = useState([]);
const handleChange = (e) => {
setMovieTitle(e.target.value);
};
const getMovieData = () => {
const apiKey = 'didntleakit';
const apiUrl = 'http://www.omdbapi.com/?apikey=' apiKey '&s='
movieTitle;
Axios.get(apiUrl)
.then((res) => {
setSearchResults([...res.data.Search]);//use spread operator for optimised code
});
};
useEffect(()=>{
console.log(searchResults);
},[searchResults])
return(
<div>
<p>Home page</p>
<TextField defaultValue="Movie" onChange={(e) => handleChange(e)}/>
<button onClick={getMovieData}/>
</div>
);
};