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
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.
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:
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:
This way, the render method will be called after the promise is resolved, ensuring that the updated data is displayed.