Reputation: 75
I was learning React and came across this code:
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
The question is how is componentDidMount called even after state gets changed, that is,
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
in right above code setInterval is called which in turn calls tick function that changes state. But after the state changes and after the component is re-rendered, is componentDidMount called again?
Upvotes: 0
Views: 152
Reputation: 1560
No you're mistaken, the componentDidMount
is called only once after render, it's the tick
function which is called again and again after every second. Let me elaborate:
After render ->
componentDidMount
is called. Inside it the setInterval
get called.setInterval
gets queued in the event queue, returns an id (a number) to this.timerID
and componentDidMount
exits.tick
function is pushed to the stack and executed after one second duration.setInterval
, it's there in the queue and again gets executed after one second.I understand that you're confused as to how the tick
is called again and again and not the componentDidMount
. See the following:
fuction parentFunction() {
setInterval(() => {
childFunction();
}, 1000);
}
parentFunction();
In ths scenario, the childFunction
is inside the setInterval
(the parentFunction
is not) and hence only childFunction
is called again and again, and not the parentFunction
.
Hope it helps :)
Upvotes: 1
Reputation: 39270
A component will mount when it's rendered for the first time or after an unmount or when you change the key prop.
So if you have a component named WillSometimesRender
it will unmount when it was rendered before but is not rendered now.
And if you have a component named KeyChange
it will unmount when rendered with a different key and then remount (see code below)
class KeyChange extends React.Component {
componentDidMount() {
console.log('key change got mounted');
}
componentWillUnmount() {
console.log('key change got unmounted');
}
render() {
return <div>key change</div>;
}
}
class WillSometimesRender extends React.Component {
componentDidMount() {
console.log('will sometimes render got mounted');
}
componentWillUnmount() {
console.log('will sometimes render got unmounted');
}
render() {
return <div>will sometimes render</div>;
}
}
const App = () => {
const [key, setKey] = React.useState(1);
return (
<div>
<button onClick={() => setKey(key => key + 1)}>
Change key
</button>
<KeyChange key={key} />
{key % 2 && <WillSometimesRender />}
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 0
Reputation: 74738
is componentDidMount called again?
No, it won't be called again. In a component render componentDidMount
gets called once on the first render only. If you need to get the previous value again there is another lifecycle method for this componentDidUpdate
. Something like:
componentDidUpdate(prevProps, prevState){
console.log(prevState);
}
Upvotes: 1