skip to Main Content

I can’t understand, why in the attached code example async componentDidMount method runs forceUpdate not immediately but waiting funcLazyLoad promise to be resolved. I expect that forceUpdate will be waiting for promise resolving only in such construction await funcLazyLoad(1000).then(this.forceUpdate)

import React from 'react'
import ReactDOM from 'react-dom'

let data = ''

async function funcLazyLoad(ms) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(ms)
    }, ms)
  })
}

class App extends React.Component {
  async componentDidMount() {
    data = await funcLazyLoad(1000)
    this.forceUpdate()
  }

  render() {
    console.log('Render')
    return <div>Hello {data}</div>
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

https://codesandbox.io/p/sandbox/practical-aryabhata-vg3h64?file=%2Fsrc%2Findex.js%3A15%2C30 .

2

Answers


  1. As JavaScript works like an interpreter,the function componentDidMount() waits for the funcLazyLoad(1000) to run, later it runs the forceUpdate().I hope this helps with your issue.

    Login or Signup to reply.
  2. In your code, the componentDidMount method is marked as async, and it contains an await statement for funcLazyLoad(1000).

    The await keyword pauses the execution of the componentDidMount method until the promise returned by funcLazyLoad(1000) is resolved.

    However, since funcLazyLoad returns a Promise that resolves after a timeout of 1000 milliseconds, the rest of the componentDidMount method (specifically, the this.forceUpdate() part) will only be executed after the promise is resolved.

    So, the sequence of events is as follows:

    1. componentDidMount is called.
    2. funcLazyLoad(1000) is invoked, and the method pauses until the promise is resolved.
    3. After a delay of 1000 milliseconds, the promise is resolved, and the data variable is updated.
    4. this.forceUpdate() is executed, triggering a re-render of the component.

    If you want to wait for the promise to resolve before calling forceUpdate, your current implementation is correct. If you want to wait for the promise to resolve within the render method before rendering the updated data, you would need to use setState instead of forceUpdate, as setState triggers a re-render upon completion:

    class App extends React.Component {
      async componentDidMount() {
        data = await funcLazyLoad(1000);
        this.setState({}); // This will trigger a re-render when the promise is resolved.
      }
    
      render() {
        console.log('Render');
        return <div>Hello {data}</div>;
      }
    }
    

    This way, the render method will be called after the promise is resolved, ensuring that the updated data is displayed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search