Liu Dongyu
Liu Dongyu

Reputation: 904

how to solve the ` Component should be written as a pure function ` error in eslint-react?

class Option extends React.Component {
  constructor(props) {
    super(props);
    this.handleClickOption = this.handleClickOption.bind(this);
  }
  handleClickOption() {
    // some code
  }
  render() {
    return (
      <li onClick={this.handleClickOption}>{this.props.option}</li>
    );
  }
}

I use eslint-config-airbnb to check the above code and it show me an error msg like Component should be written as a pure function .

So how to change the above component to pure function?

Thanks for your help.

Upvotes: 51

Views: 51318

Answers (5)

John Meyer
John Meyer

Reputation: 2356

In ES6 you might do something similar to this:

const Options = (props) => {

    const handleClickOption = () => {
        // some code
    }

    return (
        <li onClick={handleClickOption}>{props.myOptionsListItem}</li>
    );
};

Options.propTypes = {
    // validate props
};

export default Options;

Upvotes: 19

Faris Rayhan
Faris Rayhan

Reputation: 4636

It means you declare stateful component in react without construct. The scenario can be like this

import React, { Component } from 'react';

class Something extends Component {
   render() {
      return (
        <div>Your classes</div>
      )
   }
}

Above code is wrong so the right code should be like this

class Something extends Component {

   constructor(props) {
      super(props);
      this.props = props;
   }

   render() {
      return (
        <div>Your classes</div>
      )
   }
}

Upvotes: 8

optimisticupdate
optimisticupdate

Reputation: 1689

I have a similar problem. Does anybody knows how to call a component specific prop inside of the passed click-function.

E.g.

function ElementRow({onClick, element, key}) {
  return (
    <tr key={key}>
      <td><a href="#" onClick={onClick}>Delete</a></td>
      <td>
        ...
      <td>{ element.first } { element.last }</td>
    </tr>
  );
}

Inside of the onClick function I need the element.id. I am looking for a solution without using bind()

I know how to get it work with React.createClass or extend React.Component but not written as a pure function.

Edit: Found a solution but I am not sure if it's a code smell. :)

function ElementRow({ onClick, element, key }) {
  const _onClick = (e) => {
    onClick(e, element.id);
  };

  return (
    <tr key={key}>
      <td><a href="#" onClick={_onClick}>Delete</a></td>
      <td>
        ...
      </td>
      <td>{ element.first } { element.last }</td>
    </tr>
  );
}

Upvotes: 0

David L. Walsh
David L. Walsh

Reputation: 24824

React 0.14 introduced pure function components.

This should be the preferred option for all stateless components.

function Option({ onClick, option }) {
    return (
        <li onClick={onClick}>
            {option}
        </li>
    );
}

Upvotes: 53

vikram jeet singh
vikram jeet singh

Reputation: 3516

The Stateless functional components will benefit from future React performance optimizations specific to these components. Here's the way we can write component as pure function:

const App = () => {
  return (
    <div>
      <h2 id="heading">Hello ReactJS </h2>
      <header />
    </div>
  );
};

export default App;

However if you want to write component in ES6 style, you still can do but in this case the eslint error need to be removed (if you are using eslint). The following change in .eslintrc file

E.G:

"rules": {
    "react/prefer-stateless-function": "off"
}

Then here ES6 style component you can write with eslint enable:

import React, { Component } from 'react';

class Home extends Component {
  render() {
    return (
      <header className="header">
        <h1>Home page</h1>
      </header>
    );
  }
}

export default Home;

Upvotes: 16

Related Questions