Home > Enterprise >  useState not updated immediatly only after refreshing the component
useState not updated immediatly only after refreshing the component

Time:11-28

Im trying to call those enrollments from the client, when i get them i want to save them in the Enrollments and then call the getCourses(). When i save the enrollments in the useState, and i call the getCourses() and log those enrollments saved in the hook, its undefined, if i refresh or press save in VS it works fine then. Any solution on how to solve this?

const [enrollments, setEnrollments] = useState<Enrollment[]>([]);


client.v2().enrollments().fetch()).then((enrollments) => {
        setEnrollments(enrollments.enrollments);
      })
      .then(() => {
        getCourses();
      }


const getCourses = () => {
    console.log(enrollments) //Undefined in the first call, after saving it works. 
}

Im trying to call those enrollments from the client, when i get them i want to save them in the Enrollments and then call the getCourses(). When i save the enrollments in the useState, and i call the getCourses() and log those enrollments saved in the hook, its undefined, if i refresh or press save in VS it works fine then. Any solution on how to solve this?

CodePudding user response:

State is updated after rerender, you are calling it before rerender. In your case i suggest to return enrollments and then pass them as parameter:

const [enrollments, setEnrollments] = useState<Enrollment[]>([]);


client.v2().enrollments().fetch()).then((enrollments) => {
        setEnrollments(enrollments.enrollments);
        return enrollments.enrollments
      })
      .then((enrollmentsData) => {
        getCourses(enrollmentsData);
      }


const getCourses = (enrollmentsData) => {
    console.log(enrollmentsData)}

or you can use them in first then callback:

const [enrollments, setEnrollments] = useState<Enrollment[]>([]);


client.v2().enrollments().fetch()).then((enrollments) => {
        setEnrollments(enrollments.enrollments);
        getCourses(enrollments.enrollments)
      })
      


const getCourses = (enrollmentsData) => {
    console.log(enrollmentsData)}

dont forget, that this fetch will be called every render, so i suggest to put in useEffect with empty array as dependencies

const [enrollments, setEnrollments] = useState<Enrollment[]>([]);

React.useEffect(()=>{
    client.v2().enrollments().fetch()).then((enrollments) => {
        setEnrollments(enrollments.enrollments);
        getCourses(enrollments.enrollments)
      })},[]);

      


const getCourses = (enrollmentsData) => {
    console.log(enrollmentsData)}

and with that settings you can call getCourses in another useEffect instead:

const [enrollments, setEnrollments] = useState<Enrollment[]>([]);


React.useEffect(()=>{
    client.v2().enrollments().fetch()).then((enrollments) => {
        setEnrollments(enrollments.enrollments);
      })},[]);

React.useEffect(()=>{
 if(enrollments.length >0){
  getCourses()
}},[enrollments]);     

const getCourses = () => {
    console.log(enrollments)}

This will call getCourses when enrollments change and are not empty array. But i would suggest previous solution with getCourses inside then callback and passing enrollments as parameter

  • Related