Getting state updated very late and console error value was evaluated just now. How to resolve

Issue

I am totally confused about what’s happening here. I am setting the state in React but it’s updating very late. Here is the function:

fetchTimesheets() {
    const userId = cryptInfo.decrypt(localStorage.getItem('user_id'))
    var userArray = []
    var timeSheets = []
    fetchManagerProject(userId)
      .then(async (res) => {
        const projects = await res.json()
        projects.forEach(project => {
          project.teammember && project.teammember.forEach(member => {
            if (userArray.indexOf(member.user) === -1) {
              userArray.push(member.user)
              fetchUserTimelogs(member.user)
                .then(async (res) => {
                  const timesheet = await res.json()
                  if (timesheet)
                    timesheet.forEach(sheet => {
                      timeSheets.push(sheet)
                    });
                })
            }
          })
        })
        
        this.setState({
          timesheets: timeSheets
        })
      })

  }
     

I am calling this function on componentDidMount method

componentDidMount() {
    this.fetchTimesheets()
}

But I am getting that my value is evaluated just now and state is not updated. I have seen many questions related to this but didn’t get a good solution.

Solution

Have you checked to see whether it is the requests that you are making that are taking a long time or whether it’s the setState itself?

Your fetchTimesheets contains multiple http requests on a loop (forEach) which could take some time to complete depending on the request. Because the forEach loop is a blocking function it means that your setState function will not be called until the forEach functions execution has completed.

To speed this up, you could consider setting the timesheet in-state each time you get a new timesheet. For example

fetchManagerProject(userId)
    .then(async (res) => {
    const projects = await res.json()
    projects.forEach(project => {
        project.teammember && project.teammember.forEach(member => {
        if (userArray.indexOf(member.user) === -1) {
            userArray.push(member.user)
            fetchUserTimelogs(member.user)
            .then(async (res) => {
                const timesheet = await res.json()
                if (timesheet)
                timesheet.forEach(sheet => {
                    timeSheets.push(sheet)
                });
                const newTimesheet = this.state.timesheets.concat(timesheet);
                this.setState({timesheets: newTimesheet});
            })
        }
        })
    })
})

Answered By – Alex Wiley

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published