title: how to unsubscribe from subscriptions and events in componentwillunmount?
body: <p>I have a component here and it seems there's a memory leak in there
  because I am receiving the warning</p>
  
  <pre><code>Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
  </code></pre>
  
  <p>I have read about it but I am not sure how exactly to do that.
  Could you tell me how to cancel the events in the component or find the events that should be cancelled.
  if you could point me to an article or guide that helps in understanding that would be very helpful too.</p>
  
  <p>here's the code, for the component.</p>
  
  <pre><code>import React, { Component } from "react";
  import { Modal, Button, Icon, Select, Input, Row, Col, Spin } from "antd";
  //import PDFJS from './pdf';
  import styles from "./EditPdfDetailsModal.less";
  const Option = Select.Option;
  if (window.PDFJS) {
    const PDFJS = window.PDFJS;
    PDFJS.disableWorker = true;
  }
  export default class EditPdfDetailsModal extends Component {
    state = {
      file: this.props.item.file,
      categoryid: "",
      splitpdfData: "",
      urls: [],
      showSplitFiles: false,
      loading: false
    };
  
    showSplitFiles = () =&gt; {};
  
    editMergePdf = () =&gt; {
      var formData = new FormData();
      formData.append("filepath", this.props.item.pdfname);
      let editUrl = devUrl + "trip/getpdfSplitViewtripdoc?json=true";
      this.setState({ showSplitFiles: true, loading: true });
      var that = this;
      fetch(editUrl, {
        method: "post",
        credentials: "include",
        body: formData
      })
        .then(function(response) {
          return response.json();
        })
        .then(function(data) {
          let urls = [];
          for (var i = 0; i &lt; data.files.length; i++) {
            let fileurl =
              agencyLibPdfUrl + "split/" + data.dir + "/" + data.files[i];
            urls.push(fileurl);
          }
          that.setState({ splitpdfData: data, urls });
          //=================================
          if (window.PDFJS) {
            let newurl =
              "http://172.104.60.70/st_old/uploads/defaultdocs/7/split/1527165241-42557/1_1527165241-42557.pdf";
            console.log("that.img", that);
            PDFJS.getDocument(newurl).then(function getPdfHelloWorld(pdf) {
              //
              // Fetch the first page
              //
              pdf.getPage(1).then(function getPageHelloWorld(page) {
                var scale = 1.5;
                var viewport = page.getViewport(scale);
  
                //
                // Prepare canvas using PDF page dimensions
                //
                var canvas = that.img;
                var context = canvas.getContext("2d");
                canvas.height = viewport.height;
                canvas.width = viewport.width;
  
                //
                // Render PDF page into canvas context
                //
                page.render({ canvasContext: context, viewport: viewport });
              });
            });
          }
  
          //=================================
  
          //that.showSplitFiles();
          console.log("data response : ", data);
          //return data;
        })
        .catch(err =&gt; console.log(err));
    };
    handleNameChange = e =&gt; {
      console.log("name change : ", e.target.value);
      this.setState({ file: e.target.value });
    };
    handleChange = value =&gt; {
      console.log("value selected : ", value);
      this.setState({ categoryid: value });
    };
  
    submitDetails = () =&gt; {
      var formData = new FormData();
      formData.append("doc_id", this.props.item.docid);
      formData.append("docname", this.state.file);
      formData.append("id", this.props.item.docid);
      formData.append("tripid", this.props.item.tripid);
      formData.append("doctype", "important");
      formData.append("categoryid", this.state.categoryid);
      formData.append("submit", "Submit");
  
      let submitUrl =
        devUrl + "trip/editDocument/" + this.props.item.tripid + "?json=true";
      var that = this;
      fetch(submitUrl, {
        method: "post",
        credentials: "include",
        body: formData
      })
        .then(function(response) {
          return response.json();
        })
        .then(function(data) {
          that.props.getUpdatedData();
          that.props.closeModal();
          console.log("data response : ", data);
          //return data;
        })
        .catch(err =&gt; console.log(err));
    };
  
    componentWillUnmount() {}
  
    render() {
      var styling = "styles.vertical-center-modal";
      let item = this.props.item;
      let categories = this.props.impcategories;
      let categoryOptions = [];
      categories.map((item, index) =&gt; {
        let option = (
          &lt;Option key={index} value={item.categoryid}&gt;
            {" "}
            {item.categoryname}{" "}
          &lt;/Option&gt;
        );
        categoryOptions.push(option);
      });
      /*  if(this.state.urls.length&gt;0){
         if(window.PDFJS){
  
              PDFJS.getDocument(this.state.urls[0]).then(function getPdfHelloWorld(pdf) {
                   //
                   // Fetch the first page
                   //
                   pdf.getPage(1).then(function getPageHelloWorld(page) {
                     var scale = 1.5;
                     var viewport = page.getViewport(scale);
  
                     //
                     // Prepare canvas using PDF page dimensions
                     //
                     var canvas = this.img;
                     var context = canvas.getContext('2d');
                     canvas.height = viewport.height;
                     canvas.width = viewport.width;
  
                     //
                     // Render PDF page into canvas context
                     //
                     page.render({canvasContext: context, viewport: viewport});
                   });
                 });
          }
       }*/
      let formStyle = { height: "200px", width: "550px" };
      let splitPdfStyle = { height: "400px", width: "600px" };
      return (
        &lt;Modal
          visible={this.props.showModal}
          wrapClassName={styling}
          onCancel={this.props.closeModal}
          zIndex={1100}
          bodyStyle={this.state.showSplitFiles ? splitPdfStyle : formStyle}
          footer={[
            &lt;Button
              key="submit"
              type="primary"
              onClick={this.submitDetails.bind(this)}
            &gt;
              Submit
            &lt;/Button&gt;
          ]}
        &gt;
          {this.state.showSplitFiles ? (
            &lt;div&gt;
              {!this.state.loading ? (
                &lt;Spin
                  style={{ width: "100%", margin: "0 auto" }}
                  tip="Loading Pdf..."
                /&gt;
              ) : (
                &lt;div&gt;
                  show files here&lt;br /&gt;
                  &lt;canvas ref={el =&gt; (this.img = el)}&gt; &lt;/canvas&gt;
                &lt;/div&gt;
              )}{" "}
            &lt;/div&gt;
          ) : (
            &lt;div&gt;
              &lt;Row gutter={24}&gt;
                &lt;Col md={12} lg={12} xl={12}&gt;
                  Category Name:&lt;br /&gt;
                  &lt;Select
                    //defaultValue={item.type}
                    placeholder="Please Select"
                    style={{ width: 220 }}
                    onChange={this.handleChange}
                    getPopupContainer={triggerNode =&gt; triggerNode.parentNode}
                  &gt;
                    {categoryOptions}
                  &lt;/Select&gt;
                &lt;/Col&gt;
                &lt;Col md={12} lg={12} xl={12}&gt;
                  Document Name &lt;br /&gt;{" "}
                  &lt;Input
                    onChange={this.handleNameChange}
                    placeholder="Basic usage"
                    value={this.state.file}
                    style={{ width: "200px" }}
                  /&gt;
                &lt;/Col&gt;
              &lt;/Row&gt;
  
              &lt;Row&gt;
                &lt;Col&gt;
                  {" "}
                  &lt;div className={styles.buttons}&gt;
                    &lt;Button type="primary"&gt;Replace Pdf &lt;/Button&gt;
                    &lt;Button onClick={this.editMergePdf.bind(this)} type="primary"&gt;
                      Edit/Merge Pdf{" "}
                    &lt;/Button&gt;
                  &lt;/div&gt;{" "}
                &lt;/Col&gt;
                &lt;canvas ref={el =&gt; (this.imgs = el)}&gt; &lt;/canvas&gt;
              &lt;/Row&gt;
            &lt;/div&gt;
          )}
        &lt;/Modal&gt;
      );
    }
  }
  </code></pre>
  
  <p>I looked around for how to cancel the subscriptions but not sure how exactly to do that.
  for example I have a click event on a button.
  how do I cancel that event ?
  and do I need to cancel onchange events too?</p>