Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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">...
like image 221
Zena Mesfin Avatar asked Nov 07 '17 17:11

Zena Mesfin


People also ask

How do I use ESLint to fix errors?

There are three ways that ESLint fix can be run: eslint --fix will fix every rule violation it is capable of fixing, actually overwrite the code, and print out any warnings or errors it was incapable of fixing. Most errors are not actually automatically fixable. Take a look at this documentation, the items with the ‘wrench’ image can be auto-fixed.

Do warnings result in problems at runtime in ESLint?

Generally, warnings don’t directly result in problems at runtime. However, many rules can be configured to show errors instead of warnings (or vice versa). For example, both of the issues listed above are included as warnings when extending @typescript-eslint/recommended like below in .eslintrc.json:

What are the exit codes for ESLint’s Fix command?

ESLint’s fix command has three possible exit codes: 1 success and no lint errors, less warnings than max warnings 2 linting was successful, at least one lint error or more warnings than max-warnings 3 linting unsuccessful due to config error or internal error

What is ESLint--fix--fix-type?

eslint --fix --fix-type enables targeting of specific categories of issues to fix. We’ll discuss the types in more detail below, but an example command would be eslint --fix --fix-type layout.


3 Answers

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;

    // ...
  }
}
like image 198
loganfsmyth Avatar answered Nov 02 '22 23:11

loganfsmyth


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.

like image 24
Sidney Avatar answered Nov 03 '22 00:11

Sidney


turn it into static function

static savePDF() { ... }

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

like image 24
Luke Robertson Avatar answered Nov 03 '22 00:11

Luke Robertson