Reputation: 33
Why my sleep function doesn't make the React application freeze? Here's my code:
import React from "react";
import "./App.css";
function App() {
const [count, setCount] = React.useState(0);
(async () => {
const sleep = async (miliseconds: number) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("");
}, miliseconds);
});
};
await sleep(5000);
console.log("hey");
})();
return (
<div className="App">
<h1>{count}</h1>
<button onClick={() => setCount((count) => count + 1)}>+</button>
</div>
);
}
export default App;
So, I have an IIFE sleep function inside the component that is supposed to execute before every render. But when I click on the increment button of my counter, the DOM being updated immediately without waiting for my sleep function to finish its execution. What's wrong with it? If I use for loop to freeze the app everything works as expected but the sleep function implemented with promise doesn't cause my app freeze.
Upvotes: 1
Views: 629
Reputation: 371138
What this block of code does:
(async () => {
const sleep = async (miliseconds: number) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("");
}, miliseconds);
});
};
await sleep(5000);
console.log("hey");
})();
is it creates a Promise that resolves after 5 seconds. That's it. The Promise isn't used anywhere, and so it isn't connected to anything in the rest of the code.
function App() {
const [count, setCount] = React.useState(0);
// here, create a Promise that resolves after 5 seconds, and don't do anything with it
return (
<div className="App">
<h1>{count}</h1>
<button onClick={() => setCount((count) => count + 1)}>+</button>
</div>
);
}
The App
's return
still executes immediately when App
is called, so there's no delay before it renders.
If you wanted to add a render delay, conditionally render the component and set a state after 5 seconds.
function App() {
const [count, setCount] = React.useState(0);
const [render, setRender] = React.useState(false);
React.useEffect(() => {
setTimeout(() => {
setRender(true);
}, 5000);
}, []);
return !render ? null : (
<div className="App">
<h1>{count}</h1>
<button onClick={() => setCount((count) => count + 1)}>+</button>
</div>
);
}
ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>
Upvotes: 3