How can I fix 'warning Expected 'this' to be used by class method ' eslint error?

11,252

Solution 1

There are two different answers to this question, depending on how you want to handle it.

First, the reason you get this error is because of the ESLint rule https://eslint.org/docs/rules/class-methods-use-this. Specifically, this is because if something is a class method, e.g. if you are calling this.foo() to call a function, the whole reason to make it a method is because there are properties on this that you need to use.

While in many languages with class, most functions are methods, that is not the case in JS. If you have a class like

class Example {
  constructor(){
    this.data = 42;
  }
  someMethod() {
    this.someHelper(this.data);
  }

  someHelper(value){
    console.log(value);
  }
}

the someHelper function would trigger the same error you are getting, because it never uses this, so you can just as easily do

class Example {
  constructor(){
    this.data = 42;
  }
  someMethod() {
    someHelper(this.data);
  }
}

function someHelper(value){
  console.log(value);
}

In your case, you can do this. Your whole savePDF function could be moved outside of the class object.

That said, it is important to ask yourself why something like this isn't using this. In most cases, you'd expect any function that works with HTML to absolutely use this, because how else, in React, is it supposed to access the element's that React has created.

So the real answer to your question would be to drop the

const source = document.getElementById('printContainer');

line. If you need access to the HTML element being created by React, you should be using React's APIs to do so. That would be done with something like

class SavePDFButton extends React.Component {
  constructor(props) {
    super(props);

    this.printContainer = null;

    this.savePDF = this.savePDF.bind(this);
    this.handlePrintContainerRef = this.handlePrintContainerRef.bind(this);
  }

  render() {
    return (
      <div>
        <Link
          name="save-to-pdf"
          onClick={this.savePDF}
          button="secondary"
        >
          Save to PDF
        </Link>
        <div 
          id="printContainer" 
          className="cf-app-segment--alt cf-hearings-worksheet" 

          ref={this.handlePrintContainerRef}
        />
      </div>
    );
  }

  handlePrintContainerRef(el) {
    // When React renders the div, the "ref={this.handlePrintContainerRef}" will
    // make it call this function, which will store a reference.
    this.printContainer = el;
  }

  savePDF() {
    // OLD: const source = document.getElementById('printContainer');
    const source = this.printContainer;

    // ...
  }
}

Solution 2

I believe that's caused by the class-methods-use-this ESLint rule.

It's just letting you know that your function doesn't use this, so you can probably make it a static function.

Solution 3

turn it into static function

static savePDF() { ... }

Its happening because this function isnt using this meaning it dosnt need to be dynamic

Share:
11,252
Zena Mesfin
Author by

Zena Mesfin

Updated on July 16, 2022

Comments

  • Zena Mesfin
    Zena Mesfin almost 2 years

    I am creating a PDF like this inside a react Component.

    export class Test extends React.PureComponent {

    savePDF() {
      const source = document.getElementById('printContainer');
      /* eslint new-cap: ["error", { "newIsCap": false }]*/
      let pdf = new jspdf('p', 'pt', 'letter');
    
    
      let margins = { top: 50,
        left: 60,
        width: 612
      };
    
      pdf.fromHTML(
        source, 
        margins.left, 
        margins.top, 
        {
          width: margins.width
        },
        () => {
          pdf.save('worksheet.pdf');
        }
      );
    } 
    

    and I am getting warning Expected 'this' to be used by class method 'savePDF' class-me

    this is being called an click like this onClick={this.savePDF} see below

      render() {
           <Link
          name="save-to-pdf"
          onClick={this.savePDF}
          button="secondary">
            Save to PDF</Link>
           <div id="printContainer" className="cf-app-segment--alt cf-hearings-worksheet">...
    
  • Zena Mesfin
    Zena Mesfin over 6 years
    How can i create a static function? I do not know what that is!
  • Sidney
    Sidney over 6 years
    The ESLint rule page that I linked has an example: eslint.org/docs/rules/class-methods-use-this. You can learn more about static methods in JavaScript here: javascript.info/class