Reputation: 3
I just started react...
This code is simply rendered after 3 seconds using Boolean value.
But the code below keeps rendering.. rendering.. rendering... almost every three seconds.
import React, { useState } from "react";
const App = () => {
const [isLoading, setIsLoading] = useState(true);
setTimeout(() => {
setIsLoading(!isLoading);
}, 3000);
return <h1>{isLoading ? "Loading" : "we are ready"}</h1>;
};
export default App;
But this code works well. What is the reason?
import React, { Component } from "react";
class App extends React.Component {
state = {
isLoading: true,
};
componentDidMount() {
setTimeout(() => {
this.setState({
isLoading: false,
});
}, 3000);
}
render() {
return <div>{this.state.isLoading ? "Loading..." : "we are ready"}</div>;
}
}
export default App;
Upvotes: 0
Views: 162
Reputation: 2666
A function component is called on every render. That means the timeout is created on every re-render after a state change as well, when implemented like in your first example. To use the component lifecycle, you should use the useEffect
hook: https://reactjs.org/docs/hooks-reference.html#useeffect
import React, { useEffect, useState } from "react";
const App = () => {
const [isLoading, setIsLoading] = useState(true);
// Set a timeout ONCE when the component is rendered for the first time
// The second argument [] signifies that nothing will trigger the effect during re-renders
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 3000);
}, [])
return <h1>{isLoading ? "Loading" : "we are ready"}</h1>;
};
export default App;
Upvotes: 4
Reputation: 867
Answer from MubtadaNaqvi will unfortunately result in infinite loop. You should apply useEffect properly:
useEffect(() => {
setTimeout(() => {
setIsLoading(isLoading => !isLoading);
}, 1000);
}, [])
Upvotes: 0
Reputation: 197
Because you are initializing isLoading with true value in the state. and whenever the state is changed functional components rerenders, and it doesn't happen in Class-based component as you have used the component life cycle method. You should use "useEffect" in the functional component.
useEffect(() => {
setTimeout(() => {
setIsLoading(!isLoading);
}, 3000);
});
you can read about it here https://reactjs.org/docs/hooks-effect.html
Upvotes: 0