Home > Blockchain >  setState not setting value in useEffect
setState not setting value in useEffect

Time:11-15

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(
  // ...
,[])

//            
  • Related