Stacking_Flow
Stacking_Flow

Reputation: 125

Is componentWillUnmount When There is setInterval?

I am creating a simple React web application where a date and time is displayed, and the time is updated every millisecond with the setState function and setInterval function. The code is below:

import React from "react";
import TitleBar from "./TitleBar";

class Time extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      date: "",
      time: ""
    }
    this.updateTime = this.updateTime.bind(this);
  }

  componentDidMount() {
    this.interval = setInterval(() => this.updateTime, 1);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  updateTime() {
    let dateObject = new Date();
    let date = dateObject.toDateString();
    let hour = dateObject.getHours().toString();
    let minute = dateObject.getMinutes().toString();
    let second = dateObject.getSeconds().toString();
    let millisecond = dateObject.getMilliseconds().toString();
    let time = hour + " : " + minute + " : " + second + " : " + millisecond;
    this.setState({
      date: date,
      time: time
    });
  }

  render() {
    return (
      <div>
        <TitleBar/>
        <div className="time-div">
          <p className="date-txt" value={this.state.date}> {this.state.date} </p>
          <p className="time-txt" value={this.state.time}> {this.state.time} </p>
        </div>
      </div>
    );
  }
}

export default Time;

My question is, why do I need a componentWillUnmount function when the setInterval function re-renders a new time every millisecond? When I remove the componentWillUnmount function, the application works perfectly as intended, so I don't understand why I should unmount the component or "remove" the setInterval function. Is this just a convention?

Upvotes: 1

Views: 451

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1074385

My question is, why do I need a componentWillUnmount function when the setInterval function re-renders a new time every millisecond?

So that when your component is unmounted (removed from the page entirely), the interval timer is stopped and the callback stops getting called.

When I remove the componentWillUnmount function, the application works perfectly as intended,

No, it will try to set state on an unmounted component, which is an error. (Though you may not see much in terms of effects of the error except that over time your page may get slower as more and more endless intervals get scheduled and repeated. If you're using the development version of the React libs in development, they'll give you an error in the console when you try to set state on an unmounted component.)

Here's your component with that line commented out with an error message when it tries to set state after being unmounted:

class Time extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            date: "",
            time: ""
        }
        this.updateTime = this.updateTime.bind(this);
    }

    componentDidMount() {
        this.interval = setInterval(this.updateTime, 1);
    }

    componentWillUnmount() {
        // Removed to cause error: clearInterval(this.interval);
    }

    updateTime() {
        let dateObject = new Date();
        let date = dateObject.toDateString();
        let hour = dateObject.getHours().toString();
        let minute = dateObject.getMinutes().toString();
        let second = dateObject.getSeconds().toString();
        let millisecond = dateObject.getMilliseconds().toString();
        let time = hour + " : " + minute + " : " + second + " : " + millisecond;
        this.setState({
            date: date,
            time: time
        });
    }

    render() {
        return (
            <div>
                {/*Omitted for example <TitleBar />*/}
                <div className="time-div">
                    <p className="date-txt" value={this.state.date}> {this.state.date} </p>
                    <p className="time-txt" value={this.state.time}> {this.state.time} </p>
                </div>
            </div>
        );
    }
}

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            showTime: true
        };
    }
    componentDidMount() {
        this.timer = setTimeout(() => {
            this.setState({showTime: false});
        }, 200);
    }
    componentWillUnmount() {
        clearTimeout(this.timer);
    }
    render() {
        return <div>{this.state.showTime && <Time />}</div>;
    }
}

ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.development.js"></script>

Upvotes: 2

Imran Rafiq Rather
Imran Rafiq Rather

Reputation: 8098

All the SideEffects like your events which may be there (In your case setInterval and Timer associated to it is stopped) can be Cleaned Up in componentWillUnMount() just before the Component gets removed from the DOM Tree.

So, ComponentWillUnMount() is for all the CleanUp stuff, so that we avoid Memory Leaks and improve performance of our Product.

Part B:

When I remove the componentWillUnmount function, the application works perfectly as intended.

That doesn't happen actually, you may not experience it in small app. To cross verify open Developer Window and In the events section check whether the Timer functionality is still being fired or not.

Upvotes: 1

Pouya Jabbarisani
Pouya Jabbarisani

Reputation: 1121

Because if you keep setInterval after unmounting the component it will continue to run as an excess load for the browser and it can make your web application slower.

Upvotes: 0

Related Questions