Coder Social home page Coder Social logo

eslint-plugin-react's Introduction

eslint-plugin-react Version Badge

===================

github actions Maintenance Status NPM version Tidelift

React specific linting rules for eslint

Installation

npm install eslint eslint-plugin-react --save-dev

It is also possible to install ESLint globally rather than locally (using npm install -g eslint). However, this is not recommended, and any plugins or shareable configs that you use must be installed locally in either case.

Configuration (legacy: .eslintrc*)

Use our preset to get reasonable defaults:

  "extends": [
    "eslint:recommended",
    "plugin:react/recommended"
  ]

If you are using the new JSX transform from React 17, extend react/jsx-runtime in your eslint config (add "plugin:react/jsx-runtime" to "extends") to disable the relevant rules.

You should also specify settings that will be shared across all the plugin rules. (More about eslint shared settings)

{
  "settings": {
    "react": {
      "createClass": "createReactClass", // Regex for Component Factory to use,
                                         // default to "createReactClass"
      "pragma": "React",  // Pragma to use, default to "React"
      "fragment": "Fragment",  // Fragment to use (may be a property of <pragma>), default to "Fragment"
      "version": "detect", // React version. "detect" automatically picks the version you have installed.
                           // You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
                           // It will default to "latest" and warn if missing, and to "detect" in the future
      "flowVersion": "0.53" // Flow version
    },
    "propWrapperFunctions": [
        // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
        "forbidExtraProps",
        {"property": "freeze", "object": "Object"},
        {"property": "myFavoriteWrapper"},
        // for rules that check exact prop wrappers
        {"property": "forbidExtraProps", "exact": true}
    ],
    "componentWrapperFunctions": [
        // The name of any function used to wrap components, e.g. Mobx `observer` function. If this isn't set, components wrapped by these functions will be skipped.
        "observer", // `property`
        {"property": "styled"}, // `object` is optional
        {"property": "observer", "object": "Mobx"},
        {"property": "observer", "object": "<pragma>"} // sets `object` to whatever value `settings.react.pragma` is set to
    ],
    "formComponents": [
      // Components used as alternatives to <form> for forms, eg. <Form endpoint={ url } />
      "CustomForm",
      {"name": "SimpleForm", "formAttribute": "endpoint"},
      {"name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"]}, // allows specifying multiple properties if necessary
    ],
    "linkComponents": [
      // Components used as alternatives to <a> for linking, eg. <Link to={ url } />
      "Hyperlink",
      {"name": "MyLink", "linkAttribute": "to"},
      {"name": "Link", "linkAttribute": ["to", "href"]}, // allows specifying multiple properties if necessary
    ]
  }
}

If you do not use a preset you will need to specify individual rules and add extra configuration.

Add "react" to the plugins section.

{
  "plugins": [
    "react"
  ]
}

Enable JSX support.

With eslint 2+

{
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    }
  }
}

Enable the rules that you would like to use.

  "rules": {
    "react/jsx-uses-react": "error",
    "react/jsx-uses-vars": "error",
  }

Shareable configs

Recommended

This plugin exports a recommended configuration that enforces React good practices.

To enable this configuration use the extends property in your .eslintrc config file:

{
  "extends": ["eslint:recommended", "plugin:react/recommended"]
}

See eslint documentation for more information about extending configuration files.

All

This plugin also exports an all configuration that includes every available rule. This pairs well with the eslint:all rule.

{
  "plugins": [
    "react"
  ],
  "extends": ["eslint:all", "plugin:react/all"]
}

Note: These configurations will import eslint-plugin-react and enable JSX in parser options.

Configuration (new: eslint.config.js)

From v8.21.0, eslint announced a new config system. In the new system, .eslintrc* is no longer used. eslint.config.js would be the default config file name. In eslint v8, the legacy system (.eslintrc*) would still be supported, while in eslint v9, only the new system would be supported.

And from v8.23.0, eslint CLI starts to look up eslint.config.js. So, if your eslint is >=8.23.0, you're 100% ready to use the new config system.

You might want to check out the official blog posts,

and the official docs.

Plugin

The default export of eslint-plugin-react is a plugin object.

const react = require('eslint-plugin-react');
const globals = require('globals');

module.exports = [
  
  {
    files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],
    plugins: {
      react,
    },
    languageOptions: {
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
      globals: {
        ...globals.browser,
      },
    },
    rules: {
      // ... any rules you want
      'react/jsx-uses-react': 'error',
      'react/jsx-uses-vars': 'error',
     },
    // ... others are omitted for brevity
  },
  
];

Configuring shared settings

Refer to the official docs.

The schema of the settings.react object would be identical to that of what's already described above in the legacy config section.

Shareable configs

There're also 3 shareable configs.

  • eslint-plugin-react/configs/all
  • eslint-plugin-react/configs/recommended
  • eslint-plugin-react/configs/jsx-runtime

If your eslint.config.js is ESM, include the .js extension (e.g. eslint-plugin-react/recommended.js). Note that the next semver-major will require omitting the extension for these imports.

Note: These configurations will import eslint-plugin-react and enable JSX in languageOptions.parserOptions.

In the new config system, plugin: protocol(e.g. plugin:react/recommended) is no longer valid. As eslint does not automatically import the preset config (shareable config), you explicitly do it by yourself.

const reactRecommended = require('eslint-plugin-react/configs/recommended');

module.exports = [
  
  reactRecommended, // This is not a plugin object, but a shareable config object
  
];

You can of course add/override some properties.

Note: Our shareable configs does not preconfigure files or languageOptions.globals. For most of the cases, you probably want to configure some properties by yourself.

const reactRecommended = require('eslint-plugin-react/configs/recommended');
const globals = require('globals');

module.exports = [
  
  {
    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
    ...reactRecommended,
    languageOptions: {
      ...reactRecommended.languageOptions,
      globals: {
        ...globals.serviceworker,
        ...globals.browser,
      },
    },
  },
  
];

The above example is same as the example below, as the new config system is based on chaining.

const reactRecommended = require('eslint-plugin-react/configs/recommended');
const globals = require('globals');

module.exports = [
  
  {
    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
    ...reactRecommended,
  },
  {
    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
    languageOptions: {
      globals: {
        ...globals.serviceworker,
        ...globals.browser,
      },
    },
  },
  
];

List of supported rules

💼 Configurations enabled in.
🚫 Configurations disabled in.
🏃 Set in the jsx-runtime configuration.
☑️ Set in the recommended configuration.
🔧 Automatically fixable by the --fix CLI option.
💡 Manually fixable by editor suggestions.
❌ Deprecated.

Name                                  Description 💼 🚫 🔧 💡
boolean-prop-naming Enforces consistent naming for boolean props
button-has-type Disallow usage of button elements without an explicit type attribute
checked-requires-onchange-or-readonly Enforce using onChange or readonly attribute when checked is used
default-props-match-prop-types Enforce all defaultProps have a corresponding non-required PropType
destructuring-assignment Enforce consistent usage of destructuring assignment of props, state, and context 🔧
display-name Disallow missing displayName in a React component definition ☑️
forbid-component-props Disallow certain props on components
forbid-dom-props Disallow certain props on DOM Nodes
forbid-elements Disallow certain elements
forbid-foreign-prop-types Disallow using another component's propTypes
forbid-prop-types Disallow certain propTypes
function-component-definition Enforce a specific function type for function components 🔧
hook-use-state Ensure destructuring and symmetric naming of useState hook value and setter variables 💡
iframe-missing-sandbox Enforce sandbox attribute on iframe elements
jsx-boolean-value Enforce boolean attributes notation in JSX 🔧
jsx-child-element-spacing Enforce or disallow spaces inside of curly braces in JSX attributes and expressions
jsx-closing-bracket-location Enforce closing bracket location in JSX 🔧
jsx-closing-tag-location Enforce closing tag location for multiline JSX 🔧
jsx-curly-brace-presence Disallow unnecessary JSX expressions when literals alone are sufficient or enforce JSX expressions on literals in JSX children or attributes 🔧
jsx-curly-newline Enforce consistent linebreaks in curly braces in JSX attributes and expressions 🔧
jsx-curly-spacing Enforce or disallow spaces inside of curly braces in JSX attributes and expressions 🔧
jsx-equals-spacing Enforce or disallow spaces around equal signs in JSX attributes 🔧
jsx-filename-extension Disallow file extensions that may contain JSX
jsx-first-prop-new-line Enforce proper position of the first property in JSX 🔧
jsx-fragments Enforce shorthand or standard form for React fragments 🔧
jsx-handler-names Enforce event handler naming conventions in JSX
jsx-indent Enforce JSX indentation 🔧
jsx-indent-props Enforce props indentation in JSX 🔧
jsx-key Disallow missing key props in iterators/collection literals ☑️
jsx-max-depth Enforce JSX maximum depth
jsx-max-props-per-line Enforce maximum of props on a single line in JSX 🔧
jsx-newline Require or prevent a new line after jsx elements and expressions. 🔧
jsx-no-bind Disallow .bind() or arrow functions in JSX props
jsx-no-comment-textnodes Disallow comments from being inserted as text nodes ☑️
jsx-no-constructed-context-values Disallows JSX context provider values from taking values that will cause needless rerenders
jsx-no-duplicate-props Disallow duplicate properties in JSX ☑️
jsx-no-leaked-render Disallow problematic leaked values from being rendered 🔧
jsx-no-literals Disallow usage of string literals in JSX
jsx-no-script-url Disallow usage of javascript: URLs
jsx-no-target-blank Disallow target="_blank" attribute without rel="noreferrer" ☑️ 🔧
jsx-no-undef Disallow undeclared variables in JSX ☑️
jsx-no-useless-fragment Disallow unnecessary fragments 🔧
jsx-one-expression-per-line Require one JSX element per line 🔧
jsx-pascal-case Enforce PascalCase for user-defined JSX components
jsx-props-no-multi-spaces Disallow multiple spaces between inline JSX props 🔧
jsx-props-no-spreading Disallow JSX prop spreading
jsx-sort-default-props Enforce defaultProps declarations alphabetical sorting
jsx-sort-props Enforce props alphabetical sorting 🔧
jsx-space-before-closing Enforce spacing before closing bracket in JSX 🔧
jsx-tag-spacing Enforce whitespace in and around the JSX opening and closing brackets 🔧
jsx-uses-react Disallow React to be incorrectly marked as unused ☑️ 🏃
jsx-uses-vars Disallow variables used in JSX to be incorrectly marked as unused ☑️
jsx-wrap-multilines Disallow missing parentheses around multiline JSX 🔧
no-access-state-in-setstate Disallow when this.state is accessed within setState
no-adjacent-inline-elements Disallow adjacent inline elements not separated by whitespace.
no-array-index-key Disallow usage of Array index in keys
no-arrow-function-lifecycle Lifecycle methods should be methods on the prototype, not class fields 🔧
no-children-prop Disallow passing of children as props ☑️
no-danger Disallow usage of dangerous JSX properties
no-danger-with-children Disallow when a DOM element is using both children and dangerouslySetInnerHTML ☑️
no-deprecated Disallow usage of deprecated methods ☑️
no-did-mount-set-state Disallow usage of setState in componentDidMount
no-did-update-set-state Disallow usage of setState in componentDidUpdate
no-direct-mutation-state Disallow direct mutation of this.state ☑️
no-find-dom-node Disallow usage of findDOMNode ☑️
no-invalid-html-attribute Disallow usage of invalid attributes 💡
no-is-mounted Disallow usage of isMounted ☑️
no-multi-comp Disallow multiple component definition per file
no-namespace Enforce that namespaces are not used in React elements
no-object-type-as-default-prop Disallow usage of referential-type variables as default param in functional component
no-redundant-should-component-update Disallow usage of shouldComponentUpdate when extending React.PureComponent
no-render-return-value Disallow usage of the return value of ReactDOM.render ☑️
no-set-state Disallow usage of setState
no-string-refs Disallow using string references ☑️
no-this-in-sfc Disallow this from being used in stateless functional components
no-typos Disallow common typos
no-unescaped-entities Disallow unescaped HTML entities from appearing in markup ☑️
no-unknown-property Disallow usage of unknown DOM property ☑️ 🔧
no-unsafe Disallow usage of unsafe lifecycle methods ☑️
no-unstable-nested-components Disallow creating unstable components inside components
no-unused-class-component-methods Disallow declaring unused methods of component class
no-unused-prop-types Disallow definitions of unused propTypes
no-unused-state Disallow definitions of unused state
no-will-update-set-state Disallow usage of setState in componentWillUpdate
prefer-es6-class Enforce ES5 or ES6 class for React Components
prefer-exact-props Prefer exact proptype definitions
prefer-read-only-props Enforce that props are read-only 🔧
prefer-stateless-function Enforce stateless components to be written as a pure function
prop-types Disallow missing props validation in a React component definition ☑️
react-in-jsx-scope Disallow missing React when using JSX ☑️ 🏃
require-default-props Enforce a defaultProps definition for every prop that is not a required prop
require-optimization Enforce React components to have a shouldComponentUpdate method
require-render-return Enforce ES5 or ES6 class for returning value in render function ☑️
self-closing-comp Disallow extra closing tags for components without children 🔧
sort-comp Enforce component methods order
sort-default-props Enforce defaultProps declarations alphabetical sorting
sort-prop-types Enforce propTypes declarations alphabetical sorting 🔧
state-in-constructor Enforce class component state initialization style
static-property-placement Enforces where React component static properties should be positioned.
style-prop-object Enforce style prop value is an object
void-dom-elements-no-children Disallow void DOM elements (e.g. <img />, <br />) from receiving children

Other useful plugins

License

eslint-plugin-react is licensed under the MIT License.

eslint-plugin-react's People

Contributors

alexkval avatar alexzherdev avatar ariperkkio avatar bmish avatar brettdh avatar calebmorris avatar developer-bandi avatar dianasuvorova avatar dustinsoftware avatar fatfisz avatar golopot avatar jaaberg avatar jackyho112 avatar jomasti avatar jseminck avatar justinanastos avatar jzabala avatar lencioni avatar ljharb avatar lukyth avatar petersendidit avatar pfhayes avatar sergei-startsev avatar sjarva avatar snowypowers avatar thiefmaster avatar tsmmark avatar vedadeepta avatar yannickcr avatar yepninja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eslint-plugin-react's Issues

full classes compatibility (with static properties)

I just upgraded to latest version and I am getting issue with classes used as react component.
It seems some rules like displayName or prop-types are not able to read (or just don't look) static fields.

import React, {Component, PropTypes} from "react"

class Widget extends Component {

  static displayName = "Widget"

  static childContextTypes = {
    styleVariables: PropTypes.object,
    RouteHandler: PropTypes.func,
  }

  static propTypes = {
    styleVariables: PropTypes.object,
    RouteHandler: PropTypes.func,
  }

  getChildContext() {
    return {
      styleVariables: this.props.styleVariables,
      RouteHandler: this.props.RouteHandler,
    }
  }
}

This code give me 3 errors:

   6:0   error  Widget component definition is missing display name         react/display-name
  24:22  error  'styleVariables' is missing in props validation for Widget  react/prop-types
  25:20  error  'RouteHandler' is missing in props validation for Widget    react/prop-types

It would be really cool to support this.

Rule proposal: sorted props

Some people might want to enforce that their props are sorted alphabetically.

Good:

<MyComponent
  aProp="value"
  bProp="value"
  cProp="value"
/>

Bad:

<MyComponent
  cProp="value"
  aProp="value"
  bProp="value"
/>

react/jsx-quotes breaks on components with children

The following code:

const React = require('react/addons');

const Test = React.createClass({
  render: function() {
    return (
      <div>
        Hi
      </div>
    );
  }
});

module.exports = Test;

with the react/jsx-quotes rule enabled under any configuration gives the following message:

6:11  warning  JSX attributes must use singlequote  react/jsx-quotes

ESLint 0.17.1, eslint-plugin-react 1.6.0.

React components and unused vars

A common react pattern is to store a component name in a var that then only gets used inside of JSX:

var App = React.createClass({
  render: function () {
    return (
      <p>hey</p>
    );
  }
});

React.render(
  <App />,
  document.getElementById('hey')
);

I want to disallow unused variables, but I would like these to be ignored. I wonder if this plugin could handle that or if there would be some other pattern or combination of rules that could be used to cover this use case.

I'll investigate a bit more myself, but for now I was wondering if anyone else had come across this.

Rule proposal: prefer `prop` over `prop={true}`

On our team when setting props to true, we prefer leaving out the ={true}. It would be nice to have a rule that enforces this (and I suppose one that can enforce the opposite.

Good:

<MyComponent myBooleanProp anotherProp="value" />

Bad:

<MyComponent myBooleanProp={true} anotherProp="value" />

suggestion: prevent typo on some attributes

I just lose 5min because I typed "propsTypes" instead of "propTypes". It might be cool to add some warning about that ?
I am sure there is other keywords we can handle.
Not sure if this should be handled by this plugin.

react/prop-types false positive on non-component class

If I have a regular class (non-component) that has a property called props, the react/prop-types rule will complain about missing props validation.

class MyClass {
  myMethod() {
    return this.props.test;
  }
}

3:11 error 'test' is missing in props validation for MyClass react/prop-types

This should only happen for classes that extend React.Component or extend a class that extends React.Component.

eslint-plugin-react 2.0.1

React components are not detected when using ES6 classes

It seems rules are ignored with such pretty valid code

import DocumentTitle from 'react-document-title'
import PureComponent from '../../lib/purecomponent'
import {msg} from '../intl/store'

export default class About extends PureComponent {

  render() {
    return (
      <DocumentTitle title={msg('titles.about')}>
        <div className="about-page">
          <div>{this.props.fok}</div>
          <p>
            {msg('about.p')}
          </p>
        </div>
      </DocumentTitle>
    )
  }

}

props are not detected when destructuring

I like to pull the props I need into scope with destructuring

const { propA, propB } = this.props;

This plugin doesn't catch those and warn about not having propTypes.

Rule proposal: sorted propTypes

Similar to #16, some people might might to enforce that propTypes are sorted alphabetically.

Good:

propTypes: {
  aProp: React.PropTypes.object,
  bProp: React.PropTypes.object,
  cProp: React.PropTypes.object,
},

Bad:

propTypes: {
  bProp: React.PropTypes.object,
  aProp: React.PropTypes.object,
  cProp: React.PropTypes.object,
},

prop-types warns even if you don’t use props at all

The prop-types rule warns always if you don’t specify the propTypes property within a react component even if you don’t use any props.

I suggest to only warn if a used prop is not defined within propTypes. This would also be good if you have specified the propTypes property somehow but not defined every used prop.

So the following should not be considered as a warning:

var Hello = React.createClass({
  render: function() {
    return <div>Hello World</div>;
  }
});

But this should be considered as a warning:

var Hello = React.createClass({
  propTypes: {
    name: React.PropTypes.string.isRequired
  },
  render: function() {
    return <div>Hello {this.props.name} and {this.props.propWithoutTypeDefinition}</div>;
  }
});

Non Empty component violating self-closing-comp

eslint 0.14
eslint-plugin-react 1.2.1

unless my eyes deceive me, this shouldn't be a problem.
1__tmux
1__tmux

this works
1__tmux

but this doesn't
1__tmux

seems like this rule is checking for white space not true emptiness.
sanity check
1__tmux

Rule proposal: no reference to `this.isMounted`in components

I've seen some people write code like if (this.isMounted) instead of if (this.isMounted()). It might be nice to have a rule that notices the former and encourages the latter.

Good:

if (this.isMounted()) {
  ...
}

Bad:

if (this.isMounted) {
  ...
}

Feature request: propTypes shape detection

Now that we have the prop-types rule, it would be nice if it could be configured to (perhaps by default) help you find properties on objects from props that you are using. For instance:

const React = require('react/addons');

const MyComponent = React.createClass({
  propTypes: {
    myObj: React.PropTypes.object,
  },

  /**
   * @return {Object}
   */
  render: function() {
    const { myObj } = this.props;

    return (
      <div>{myObj.body}</div>
    );
  }
});

module.exports = MyComponent;

It would be nice if this plugin told me that myObj.body is missing from the shape of myObj. Where this would not raise any warnings/errors:

const React = require('react/addons');

const MyComponent = React.createClass({
  propTypes: {
    myObj: React.PropTypes.shape({
      body: PropTypes.string,
    }),
  },

  /**
   * @return {Object}
   */
  render: function() {
    const { myObj } = this.props;

    return (
      <div>{myObj.body}</div>
    );
  }
});

module.exports = MyComponent;

Error: Definition for rule 'jsx-uses-vars' was not found.

I am getting the following error:

$ ./node_modules/.bin/eslint index.js
Error: Definition for rule 'jsx-uses-vars' was not found.
    at /dev/tmp/node_modules/eslint/lib/eslint.js:657:27
    at Array.forEach (native)
    at EventEmitter.module.exports.api.verify (/dev/tmp/node_modules/eslint/lib/eslint.js:630:16)
    at processFile (/dev/tmp/node_modules/eslint/lib/cli-engine.js:193:27)
    at /dev/tmp/node_modules/eslint/lib/cli-engine.js:293:26
    at walk (/dev/tmp/node_modules/eslint/lib/util/traverse.js:81:9)
    at /dev/tmp/node_modules/eslint/lib/util/traverse.js:102:9
    at Array.forEach (native)
    at traverse (/dev/tmp/node_modules/eslint/lib/util/traverse.js:101:11)
    at CLIEngine.executeOnFiles (/dev/tmp/node_modules/eslint/lib/cli-engine.js:284:9)

I have the following setup:

package.json:

{
  ...
  "devDependencies": {
    "eslint": "^0.17.0",
    "eslint-plugin-react": "^1.5.0"
  }
}

.eslintrc:

{
    "plugins": [
        "eslint-plugin-react"
    ],
    "ecmaFeatures": {
        "jsx": true
    },
    "env": {
        "es6": true
    },
    "rules": {
        "jsx-uses-vars": 1,
        "react-in-jsx-scope": 1
    }
}

index.js:

var React = require('react');

module.exports = React.createElement({
  render() {
    return <div>Foo</div>
  }
});

Any insights on what I'm doing wrong?

`no-did-mount-set-state` is triggered by `setState` in ES6 arrow functions

This code triggers the no-did-mount-set-state rule:

React.createClass({
  //...
  componentDidMount() {
    someClass.onSomeEvent((data) => this.setState({data: data});
  }
  //...
}

The error is triggered both when I use an expression and a statement body after the arrow (i.e. with curly braces).
This shouldn't trigger the rule, since the callbacks are obviously not invoked during componentDidMount but only at a later time.

react/display-name rule firing of regular classes

When defining plain Javascript classes (not React component classes), the display-name still fires. It shouldn't.

class Test {
    constructor() {
    }
}
// From ESlint
App component definition is missing display name [react/display-name] class App {

`react-in-jsx-scope` doesn't work with ES6 imports

This doesn't work

import React from 'react/addons'

const Button = React.createClass({
  render() {
    return (
      <button {...this.props}>{this.props.children}</button>
    )
  }
})

export default Button

but if I define it as a variable it does

import r from 'react/addons'
const React = r

const Button = React.createClass({
  render() {
    return (
      <button {...this.props}>{this.props.children}</button>
    )
  }
})

export default Button

Rule proposal: require closing bracket on new line

A rule that enforces that the closing bracket of a component must be on its own line might be nice.

Good:

<MyComponent
  firstProp="value"
  secondProp="value"
/>

Bad:

<MyComponent
  firstProp="value"
  secondProp="value" />

no-undef mark JSX elements as not defined

With

var React =require('react'),
    Router = require('react-router'),
    Route = Router.Route,
    DefaultRoute = Router.DefaultRoute;

at the top and using [email protected] and [email protected] with
"react/jsx-uses-react": 1, "react/jsx-uses-vars": 1

This works fine.

var routes = React.createClass({
  render: function() {
    return (
      <Route
        name='app'
        path='/'
        handler={ App }>

        <Route
          name='bonfires'
          path='/bonfires/?:bonfires?'
          handler={ Bonfires } />

        <DefaultRoute
          handler={ Bonfires } />
      </Route>
    );
  }
});

But this barphs all over the place

var routes = (
  <Route 
    name='app'
    path='/'
    handler={ App }>

    <Route
      name='bonfires'
      path='/bonfires/?:bonfires?'
      handler={ Bonfires } />

    <DefaultRoute
      handler={ Bonfires } />
  </Route>
);

1__tmux

react/prop-types false positive on component class with static get propTypes()

If I have a class that has a property called props, the react/prop-types rule will complain about missing props validation even if it is defined in a static get propTypes

import React from 'react';
class MyClass extends React.Component {
  static get propTypes() {
    return {
      test: React.PropTypes.bool,
    };
  }
  myMethod() {
    return this.props.test;
  }
}

9:11 error 'test' is missing in props validation for MyClass react/prop-types
This should not happen since the test prop is being validated

eslint-plugin-react 2.0.2

Rule proposal: require `key` prop for rendered array items

I'm not sure how feasible this would be to implement, but it would be really great if we could catch this before runtime.

Good:

<div>
  {myArray.map(item => <div key={item.id}>{item.body}</div>)}
</div>

Bad:

<div>
  {myArray.map(item => <div>{item.body}</div>)}
</div>

Rule proposal: indent props

A rule that enforces that props on their own lines are indented properly might be nice.

Good:

<MyComponent
  firstProp="value"
  secondProp="value"
/>

Bad:

<MyComponent
firstProp="value"
secondProp="value"
/>

How to pass JSX files to eslint correctly?

I'm not sure if this is the right place (might be more of a core question). Anyway, is there a neat way to pass jsx files to eslint? Now I'm doing something like eslint lib/*.jsx. Globstar (*/) doesn't appear to be supported and this crashes if no jsx files are found. Is it possible to set .eslintrc to look for certain formats for instance? How do you deal with this problem?

Rule definitions not found (probably user error)

I'm guessing this is user error, but can someone tell me why this doesn't work?

$ grep version node_modules/eslint-plugin-react/package.json 
  "version": "2.0.2",


$ grep version node_modules/eslint/package.json 
  "version": "0.18.0",


$ cat config.json 
{
  "rules": {
    "react/jsx-no-undf": 1
  },
  "plugins": [
    "react"
  ],
  "ecmaFeatures": {
    "jsx": true
  }
}


$ cat test.jsx 
console.log("foo");


$ ./node_modules/.bin/eslint -c config.json test.jsx 

/Users/dmnd/github/kultur/node_modules/eslint/lib/eslint.js:657
                    throw new Error("Definition for rule '" + key + "' was not
                          ^
Error: Definition for rule 'react/jsx-no-undf' was not found.
    at /Users/dmnd/github/kultur/node_modules/eslint/lib/eslint.js:657:27
    at Array.forEach (native)
    at EventEmitter.module.exports.api.verify (/Users/dmnd/github/kultur/node_modules/eslint/lib/eslint.js:630:16)
    at processFile (/Users/dmnd/github/kultur/node_modules/eslint/lib/cli-engine.js:193:27)
    at /Users/dmnd/github/kultur/node_modules/eslint/lib/cli-engine.js:293:26
    at walk (/Users/dmnd/github/kultur/node_modules/eslint/lib/util/traverse.js:81:9)
    at /Users/dmnd/github/kultur/node_modules/eslint/lib/util/traverse.js:102:9
    at Array.forEach (native)
    at traverse (/Users/dmnd/github/kultur/node_modules/eslint/lib/util/traverse.js:101:11)
    at CLIEngine.executeOnFiles (/Users/dmnd/github/kultur/node_modules/eslint/lib/cli-engine.js:284:9)

Rule proposal: indentation of closing bracket

Similar to #14 and #15, it might be nice to have a rule that specifies the indentation of closing brackets for JSX.

For non-self-closing tags, I've seen three different patterns: on the same line as last prop (should maybe be handled by #14), on new line but same indentation as props, and on new line but same indentation as opening bracket.

Same line:

<MyComponent
  myProp="...">
  Children
</MyComponent>

New line, same indentation as props:

<MyComponent
  myProp="..."
  >
  Children
</MyComponent>

New line, same indentation as opening bracket:

<MyComponent
  myProp="..."
>
  Children
</MyComponent>

For self-closing tags, I've seen the same patterns, but one might want to be able to specify differences. For example, one might want to have non-self-closing be at same indentation as props, but self closing to be at same indentation as opening bracket:

<MyComponent
  myProp="..."
  >
  Children
</MyComponent>

<MyComponent
  myProp="..."
/>

Wrong line:col number for react/prop-types

Bet.js

"use strict";

var React = require("react");
var BetSlipActionCreators = require("../actions/BetSlipActionCreators");
var BetSlipStore = require("../stores/BetSlipStore");

var Bet = React.createClass({
    getInitialState: function() {
        return {
            active: false
        };
    },
    componentDidMount: function() {
        BetSlipStore.addChangeListener(this._onChange);
    },

    componentWillUnmount: function() {
        BetSlipStore.removeChangeListener(this._onChange);
    },

    _onChange: function() {
        this.setState({active: BetSlipStore.isBetInBetSlip(this.props.id)});
    },

    handleClick: function() {
        var inBetSlip = BetSlipStore.isBetInBetSlip(this.props.id);

        if (inBetSlip) {
            BetSlipActionCreators.remove(this.props.id);
        } else {
            BetSlipActionCreators.add(this.props.id);
        }

        this.setState({active: !inBetSlip});
    },
    render: function() {
        var className = "Bet";
        if (this.state.active) {
            className += " active";
        }

        return (
            <div className={className} onClick={this.handleClick}>
                <div className="Bet__title">{this.props.title}</div>
                <div className="Bet__odd">{this.props.odd.toFixed(2)}</div>
            </div>
        );
    }
});

module.exports = Bet;

Output:

/home/message/www/java-frontend-webapp/src/js/components/Bet.js
  7:28  error  'id' is missing in props validation     react/prop-types
  7:28  error  'id' is missing in props validation     react/prop-types
  7:28  error  'id' is missing in props validation     react/prop-types
  7:28  error  'id' is missing in props validation     react/prop-types
  7:28  error  'title' is missing in props validation  react/prop-types
  7:28  error  'odd' is missing in props validation    react/prop-types

ES6 classes aren't being registered as defined with react/jsx-no-undef

(First seen in #24)

It would appear that react/jsx-no-undef isn't working properly (according to @yannickcr that's what I'm seeing here) while using babel-eslint. Here's the problems:

class RalphMacchio extends React.Component {
 ...blah blah
}

and...

React.render(<RalphMacchio />, document.getElementById('rm'));

Gives me:

src/app.jsx
  41:14  error  'RalphMacchio' is not defined  react/jsx-no-undef
  41:14  error  'RalphMacchio' is not defined  no-undef

Forgive me (and point me in the right direction) if this is unrelated. I'm trying to switch to ESLint to support my new ES6 projects. Here's my WIP .eslintrc:

{
    "parser": "babel-eslint",
    "env": {
        "node": true,
        "es6": true
    },

    "plugins": [
        "react"
    ],

    "settings": {
        "ecmascript": 6
    },

    "ecmaFeatures": {
        "jsx": true
    },

    "rules": {
        "no-undef": 2,
        "react/jsx-no-undef": 2,
        "no-unused-vars": 2,
        "react/jsx-uses-vars": 1,
        "no-console": 1,
        "eqeqeq": [2, "smart"],
        "quotes": [2, "single"]
    },

    "globals": {
        "document": true,
        "window": true,
        "_": true
    }
}

Rule proposal: order of component methods

Some people like to order component methods in the order of its lifecycle. This is mentioned in https://reactjsnews.com/react-style-guide-patterns-i-like/ and the example he uses is:

React.createClass({  
  displayName : '',
  propTypes: {},
  mixins : [],
  getInitialState : function() {},
  componentWillMount : function() {},
  componentWillUnmount : function() {},
  _onChange : function() {},
  _onCreate : function() {},
  render : function() {}
});

The list of lifecycle methods can be found at https://facebook.github.io/react/docs/component-specs.html

Cannot read property 'length' of undefined in lib/rules/prop-types.js line 51

After upgrading from 1.3.0 to 1.4.1, I am getting this error message:

/path/to/project/node_modules/eslint-plugin-react/lib/rules/prop-types.js:51
        for (var i = 0, j = property.value.properties.length; i < j; i++) {
                                                     ^
TypeError: Cannot read property 'length' of undefined
    at /path/to/project/node_modules/eslint-plugin-react/lib/rules/prop-types.js:51:54
    at Array.forEach (native)
    at EventEmitter.ObjectExpression (/path/to/project/node_modules/eslint-plugin-react/lib/rules/prop-types.js:46:23)
    at EventEmitter.emit (events.js:117:20)
    at Controller.controller.traverse.enter (/path/to/project/node_modules/eslint/lib/eslint.js:683:25)
    at Controller.__execute (/path/to/project/node_modules/eslint/node_modules/estraverse/estraverse.js:397:31)
    at Controller.traverse (/path/to/project/node_modules/eslint/node_modules/estraverse/estraverse.js:495:28)
    at EventEmitter.module.exports.api.verify (/path/to/project/node_modules/eslint/lib/eslint.js:676:24)
    at processFile (/path/to/project/node_modules/eslint/lib/cli-engine.js:172:23)
    at /path/to/project/node_modules/eslint/lib/cli-engine.js:271:26
    at /path/to/project/node_modules/eslint/lib/util/traverse.js:61:17

no-unused-vars and no-undef don't work correctly when assigning JSX to variables

The following code:

const React = require('react/addons');
const Things = require('react-router');

const { Thing, AnotherThing } = Things;

const stuff = (
  <Thing>
    <AnotherThing />
  </Thing>
);

const Test = React.createClass({
  render: function() {
    return stuff;
  }
});

module.exports = Test;

Generates the following messages:

4:8   error  Thing is defined but never used         no-unused-vars
4:15  error  AnotherThing is defined but never used  no-unused-vars
7:3   error  'Thing' is not defined                  no-undef
8:5   error  'AnotherThing' is not defined           no-undef

But this code is clean:

const React = require('react/addons');
const Things = require('react-router');

const { Thing, AnotherThing } = Things;

const Test = React.createClass({
  render: function() {
    return (
      <Thing>
        <AnotherThing />
      </Thing>
    );
  }
});

module.exports = Test;

ESLint 0.17.1, eslint-plugin-react 1.6.0, with the following config:

react/jsx-uses-react: 1
react/jsx-uses-vars: 1
react/react-in-jsx-scope: 1

Rule proposal: prop quotes

Similar to ESLint's built-in quotes rule, it would be nice to have a rule that enforces the style of quotes used for props. For instance, if set to "double":

Good:

<MyComponent myProp="value" />

Bad:

<MyComponent myProp='value' />

Rule 'jsx-uses-vars': why not on by default?

Thanks for this plugin! Very cool.

I'm thinking about adopting this for my default setup across the org, but just wondering why jsx-uses-vars wouldn't be turned on by default (maybe to 'warn')? I guess the real question is: what's the use case for not wanting to mark them used?

Also, I'm totally willing to PR a change, but just wanted to get your feedback first. And if the consensus is no rule should be on by default, can we invert the language of the rule to something like jsx-ignore-var-usage?

Rule proposal: one prop per line

It might be nice to enforce only having one prop per line.

Good:

<MyComponent
  firstProp="value"
  secondProp="value"
/>

Bad:

<MyComponent firstProp="value" secondProp="value" />

Or maybe it could be configured to only apply to multiline components. In which case:

Good:

<MyComponent firstProp="value" secondProp="value" thirdProp="value" />

Bad:

<MyComponent firstProp="value" secondProp="value"
  thirdProp="value" />

Prop-type rule doesn't work in getInitialState

I've noticed the rule doesn't work when the props are used in getInitialState.
Here is a test case:

var React = require('react');
React.createClass({
    propTypes: {
        initialValue: React.PropTypes.number
    },

    getDefaultProps: function() {
        return {
            initialValue: 0
        };
    },

    getInitialState: function() {
        return {
            value: this.props.initialValue
        };
    },

    render: function() {
        return null;
    }
});

react/jsx-uses-react (react/react-in-jsx-scope) doesn't work

Hi! I'm using "eslint-plugin-react": "^2.0.2" and have some weird issues with it on one specific file. In other cases it working great, thank you :)

Eslint output:

src/routes.js
   3:4  error    React is defined but never used          no-unused-vars
   7:4  error    Route is defined but never used          no-unused-vars
   8:4  error    DefaultRoute is defined but never used   no-unused-vars
  30:2  warning  'React' must be in scope when using JSX  react/react-in-jsx-scope
  31:4  warning  'React' must be in scope when using JSX  react/react-in-jsx-scope
  33:4  warning  'React' must be in scope when using JSX  react/react-in-jsx-scope

In .eslintrc

        "no-unused-vars": [2, {"vars": "all", "args": "after-used"}],
        "react/jsx-uses-react": [1],
        "react/jsx-uses-vars": [1],
        "react/react-in-jsx-scope": [1],

In src/routes.js:

'use strict';

var React = require('react');

var Router = require('react-router');

var Route = Router.Route,
    DefaultRoute = Router.DefaultRoute;

var App = require('./components/app/app'),
    Dashboard = require('./components/dashboard/dashboard'),
    Search = require('./components/search/search');

var UserList = require('./components/user/list'),
    UserView = require('./components/user/view'),
.....skipped......

module.exports = (
  <Route path="/ui" handler={App}>
    <Route name="dashboard" path="/ui" handler={Dashboard} />

    <Route name="users" handler={UserList} />
    <Route name="user" path="/ui/users/:id" handler={UserView} />

.....skipped......
    <DefaultRoute handler={Dashboard} />
  </Route>
);

I hope I just overlooked something in configuration, but what exact?

prop-types crashes when using props as a spread attribute

The following code causes the prop-types rule to crash:

render: function () {
    return (
        <AnyElement {...this.props}>
             hello world
       </AnyElement>
    );
}
TypeError: Cannot read property 'name' of undefined
    at EventEmitter.MemberExpression (my-project/node_modules/eslint-plugin-react/lib/rules/prop-types.js:39:46)
    at EventEmitter.emit (events.js:129:20)
    at Controller.controller.traverse.enter (my-project/node_modules/eslint/lib/eslint.js:683:25)
    at Controller.__execute (my-project/node_modules/eslint/node_modules/estraverse/estraverse.js:397:31)
    at Controller.traverse (my-project/node_modules/eslint/node_modules/estraverse/estraverse.js:495:28)
    at EventEmitter.module.exports.api.verify my-project/node_modules/eslint/lib/eslint.js:676:24)
    at processFile (my-project/node_modules/eslint/lib/cli-engine.js:172:23)
    at my-project/node_modules/eslint/lib/cli-engine.js:271:26
    at my-project/node_modules/eslint/lib/util/traverse.js:61:17
    at Array.forEach (native)

Implement no-unused-vars

Feature request for shadowing ESLints no-unused-vars rule. Currently if you have:

<button onClick={e => this.close()}>Close</button>

You're not warned that you have an unused variable (e).

Support @jsx pragma

In addition to supporting React, babel supports generic JSX transforms, using a pragma like this:

/** @jsx mypackage.doSomething */

demo

Would it be possible to respect this pragma. It's not a Babel invention, to my knowledge React itself required it until recently. In the case in the demo, observing the pragma would mean not only ignoring the fact that React is not defined (react-in-jsx-scope), but also ensuring that mypackage.doSomething is defined.

I am currently working on a project using jsx in a non-React context, and I imagine I am not the only one.

JSX spread operator not supported?

eslint 0.18.0 with eslint-react-plugin 2.0.1 returns Unexpected token .. with a JSX spread operator:

spread.js:

let { aprop, ...other } = this.props

.eslintrc:

{
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "ecmaFeatures": {
    "modules": true,
    "jsx": true,
    "destructuring": true,
    "spread": true,
    "arrowFunctions": true,
    "blockBindings": true
  },
  "plugins": [
    "react"
  ],
  "rules": { // 0=off, 1=warning, 2=error
    // Strict mode
    "strict": [2, "global"],

    // React (eslint-plugin-react)
    "react/jsx-no-undef": 1,
    "react/jsx-uses-react": 1,
    "react/jsx-uses-vars": 1,
    "react/no-did-mount-set-state": 1,
    "react/no-did-update-set-state": 1,
    "react/no-unknown-property": 1,
    "react/prop-types": 1,
    "react/react-in-jsx-scope": 1,
    "react/self-closing-comp": 1,
    "react/wrap-multilines": 1,
  }
}
$ eslint spread.js

spread.js
  1:14  error  Unexpected token ..
$ eslint --version
v0.18.0
$ grep "version" node_modules/eslint-plugin-react/package.json
  "version": "2.0.1",

react/prop-types warns about destructured spread `other` properties

Sometimes a component does not care about various properties it receives -- they are just passed on to children as-is, and as per the FB docs the canonical way to do this is via a destructuring assignment with a spread operator on the last variable.

prop-types warns that props validation is missing for that other variable:

warning  'other' is missing in props validation  react/prop-types

I don't think react/prop-types should raise a warning about these "other" properties.

A Proposal: add some defaults for prop-types to ignore

As in React.Children said:

React.Children provides utilities for dealing with the this.props.children opaque data structure.

props.children has an opaque type.

So maybe it would be wise to add it into some kind of defaults list to ignore.

For now it needs to be added

"react/prop-types": [1, { ignore: [children] }]

into .eslintrc.

Same is true for className (and maybe for some more, that I'm not aware of yet).

I am new to React development and I believe I just don't know something related to written above,
so I'm looking for help with this idea.

If it turns up the idea is right one, I could try to implement it (with tests and docs of course).

Rule proposal: no attributes named "class" and "htmlFor" on jsx dom elements

To catch the case where people paste in some html and forget to change 'class' to 'className':

<div class="foo"></div>

Looking at the react source (lib/HTMLDOMPropertyConfig.js), I see these:

  DOMAttributeNames: {
    acceptCharset: 'accept-charset',
    className: 'class',
    htmlFor: 'for',
    httpEquiv: 'http-equiv'
  }

Variable are not properly marked as used when modules or globalReturn are enabled

src/widget.js

"use strict";

var React = require("react")
var HelloWorld = require("op/HelloWorld")

React.render(
  <div className="op-Widget">
    <HelloWorld />
  </div>,
  document.getElementById("op-Widget")
)

.eslintrc

ecmaFeatures:
  modules: true
  # spread: true
  jsx: true

env:
  es6: true
  browser: true
  node: true

globals:
  __DEV__: true
  __PROD__: true

plugins:
  - react

#0: off, 1: warning, 2: error
rules:
  # semicolons are useless
  semi: 0

  # @todo use the line below
  quotes: [2, "double"]

  #2 spaces indentation,
  indent: [2, 2]

  # trailing coma are cool for diff
  comma-dangle: [2, "always"]

  # enforce comma at eol (never before)
  comma-style: [2, "last"]

  valid-jsdoc: 1

  # eslint-plugin-react rules
  react/no-multi-comp: 2
  react/prop-types: 2
  react/display-name: 2
  react/wrap-multilines: 2
  react/self-closing-comp: 2
  react/no-did-mount-set-state: 2
  react/no-did-update-set-state: 2
  react/jsx-uses-react: 2
  react/react-in-jsx-scope: 2

Gives

$ eslint src/widget.js

src/widget.js
   8:4  error  HelloWorld is defined but never used     no-unused-vars
  11:2  error  'React' must be in scope when using JSX  react/react-in-jsx-scope
  12:4  error  'React' must be in scope when using JSX  react/react-in-jsx-scope
  12:5  error  'HelloWorld' is not defined              no-undef

✖ 4 problems (4 errors, 0 warnings)

What am I missing ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.