I'm making an async call inside useEffect. When the promise resolves, I am able to successfully log the data in the response. However, after I set state and index into it, I get an empty array and an error. How come my array did not get set? I am using Typescript.
const [codeTemplate, setCodeTemplate] = useState([])
const [code, setCode] = useState("")
useEffect(() => {
getQuestion({questionName}.questionName)
.then(resp => {
console.log(resp.data.question_template)
setCodeTemplate(resp.data.question_template)
console.log(codeTemplate)
setCode(codeTemplate[0]['boilerplate'])
})
}, [])
Console output:
(3) [{...}, {...}, {...}]
[]
QuestionPage.tsx:79 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'boilerplate')
CodePudding user response:
setState function in react is asynchronous if you try to console.log after it the results might still not be saved but if you try to console.log after a while (like 1,2 seconds) it will console your results and here is a small code for declaration
import { useState, useEffect } from 'react';
import './App.css';
function App() {
const [user, setUser] = useState([]);
useEffect(() => {
let promise = new Promise(resolve => resolve(fetch('https://jsonplaceholder.typicode.com/users').then(result => result.json())));
promise.then(result => setUser({ user: result }));
console.log(user);
// it will consile [] empty array
}, [])
return (
<div className='App'>
<button onClick={() => console.log({ user })}> test</button>
{/* here when you click the user will exist */}
</div>
);
}
export default App;
if you want to see the results from setState in class component it used to have a callback function as a second arg, but now it is not in the hook version(useState).
if you are trying to get value out of your response you can use setCode() directly like
setCode(resp.data.question_template[0]['boilerplate'])
CodePudding user response:
When the state
had changed, the re-render begins.
And the setState()
is asynchronous.
So console.log(codeTemplate)
in useEffect()
are always empty array.(its init value)
Move console.log(codeTemplate)
out of useEffect()
.
useEffect(
// ...
,[])
//