Hinesh Patel
Hinesh Patel

Reputation: 1251

Expected 'this' to be used by class method

In my class, eslint is complaining "Expected 'this' to be used by class method 'getUrlParams'

Here is my class:

class PostSearch extends React.Component {
  constructor(props) {
    super(props);
    this.getSearchResults();
  }

  getUrlParams(queryString) {
    const hashes = queryString.slice(queryString.indexOf('?') + 1).split('&');
    const params = {};

    hashes.forEach((hash) => {
      const [key, val] = hash.split('=');
      params[key] = decodeURIComponent(val);
    });

    return params;
  }

  getSearchResults() {
    const { terms, category } = this.getUrlParams(this.props.location.search);
    this.props.dispatch(Actions.fetchPostsSearchResults(terms, category));
  }

  render() {
    return (
      <div>
        <HorizontalLine />
        <div className="container">
          <Col md={9} xs={12}>
            <h1 className="aboutHeader">Test</h1>
          </Col>
          <Col md={3} xs={12}>
            <SideBar />
          </Col>
        </div>
      </div>
    );
  }
}

What is the best approach to solve this or refactor this component?

Upvotes: 110

Views: 161775

Answers (8)

Yitbarek Wendimu
Yitbarek Wendimu

Reputation: 9

One, who is facing the same issue, can do this and fix it. Start the function with /* eslint-disable class-methods-use-this */ comment and close with /* eslint-enable class-methods-use-this */. Like this:-

    /* eslint-disable class-methods-use-this */
    getUrlParams(queryString) {
      // some codes here
    }
    /* eslint-enable class-methods-use-this */

Upvotes: -1

Rael Gugelmin Cunha
Rael Gugelmin Cunha

Reputation: 3532

The current eslint documentation for this linter says:

This rule is aimed to flag class methods that do not use this.

And:

If a class method does not use this, it can sometimes be made into a static function.

So, applying their example to your code we'll have:

class PostSearch extends React.Component {
  constructor(props) {
    super(props);
    this.getSearchResults();
  }

  static getUrlParams(queryString) {
    const hashes = queryString.slice(queryString.indexOf('?') + 1).split('&');
    const params = {};

    hashes.forEach((hash) => {
      const [key, val] = hash.split('=');
      params[key] = decodeURIComponent(val);
    });

    return params;
  }

  getSearchResults() {
    const { terms, category } = PostSearch.getUrlParams(this.props.location.search);
    this.props.dispatch(Actions.fetchPostsSearchResults(terms, category));
  }

  render() {
    return (
      <div>
        <HorizontalLine />
        <div className="container">
          <Col md={9} xs={12}>
            <h1 className="aboutHeader">Test</h1>
          </Col>
          <Col md={3} xs={12}>
            <SideBar />
          </Col>
        </div>
      </div>
    );
  }
}

Notice the static modifier to the function and the class name before invoking the function (instead of this).

Upvotes: 3

Arjun G
Arjun G

Reputation: 2284

My solution is to use this function outside of class and bind this function to class.

function getUrlParams(queryString) {
 const hashes = queryString.slice(queryString.indexOf('?') + 1).split('&');
 const params = {};
 hashes.forEach((hash) => {
  const [key, val] = hash.split('=');
  params[key] = decodeURIComponent(val);
 });
 return params;
}
class PostSearch extends React.Component {
  constructor(props) {
    super(props);
    this.getSearchResults();
    this.getUrlParams = getUrlParams.bind(this); // add this
  }

  getSearchResults() {
   const { terms, category } = this.getUrlParams(this.props.location.search);
   this.props.dispatch(Actions.fetchPostsSearchResults(terms, category));
  }
  render() {
   return (  "bla bla"  );
  }
}

Upvotes: 5

Amir-Mousavi
Amir-Mousavi

Reputation: 4561

you should bind the function to this as the ESLint error says "Expected 'this' to be used by class method 'getUrlParams'

getUrlParams = (queryString) => { .... }

as you are not using getUrlParams during render (like onClick()) so the above technique is good which we can call it "usage of arrow function in class property".

there are other ways of binding too:

  • binding in constructor this.getUrlParams=this.getUrlParams.bind(this)
  • arrow function in render e.g.onClick={()=>this.getUrlParams()} assumed that function does not have params.
  • and React.createClass which with ES6 does not make sense :)

Upvotes: 71

rfdc
rfdc

Reputation: 1785

getUrlParams = queryString => { ... }

Upvotes: 10

Shubhendu Vaid
Shubhendu Vaid

Reputation: 567

A possible hack to this rule could be.

getMoviesByID(){
  //Add a reference to this in your function.
  this.funcName = 'getMoviesByID';
}

Upvotes: -9

Faris Rayhan
Faris Rayhan

Reputation: 4636

Another use case could be.

Let's say you have method called handlePasswordKeyUp. The body of function can be seen like this.

handlePasswordKeyUp() {
  console.log('yes')
}

Above code will trigger that error. So at least use this inside the body function

handlePasswordKeyUp(){
   this.setState({someState: someValue})
}

Upvotes: 4

Ioan
Ioan

Reputation: 5187

This is a ESlint rule, see class-methods-use-this.

You could extract the method getUrlParams and put it into a helper, or to make it static.

What could you also do is to move the this.props.location.search inside the method, therefore calling the this.getUrlParams() method without parameter, as it seems you are using it only once.

Therefore, this could look like:

getUrlParams() {
    const queryString = this.props.location.search;
    ...
    return params;
  }

A last option would be to disable this ESlint rule.

Upvotes: 30

Related Questions