Rules for consistent code formatting, component organization, and style conventions in React applications. These rules ensure maintainable and readable React codebases.
Rules for organizing components and their internal structure.
const organizationRules = {
/** Enforce component methods order */
'react/sort-comp': ESLintRule;
/** Enforce consistent placement for static properties */
'react/static-property-placement': ESLintRule;
/** Enforce destructuring assignment for props, state, and context */
'react/destructuring-assignment': ESLintRule;
/** Enforce consistent function component definition style */
'react/function-component-definition': ESLintRule;
};Usage Examples:
// ✓ Good - Proper component method order
class MyComponent extends React.Component {
// Static properties first
static propTypes = {
name: PropTypes.string
};
static defaultProps = {
name: 'Anonymous'
};
// Constructor
constructor(props) {
super(props);
this.state = { count: 0 };
}
// Lifecycle methods
componentDidMount() {
this.initializeComponent();
}
componentDidUpdate(prevProps) {
if (prevProps.name !== this.props.name) {
this.handleNameChange();
}
}
// Event handlers and custom methods
handleClick = () => {
this.setState({ count: this.state.count + 1 });
}
initializeComponent() {
// Initialization logic
}
// Render method last
render() {
return (
<div>
<span>{this.props.name}: {this.state.count}</span>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}
// ✓ Good - Destructuring assignment
const MyComponent = ({ name, age, onAction }) => {
const [count, setCount] = useState(0);
return (
<div>
<span>{name} ({age}): {count}</span>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={onAction}>Action</button>
</div>
);
};
// ✗ Bad - No destructuring
const MyComponent = (props) => {
const [count, setCount] = useState(0);
return (
<div>
<span>{props.name} ({props.age}): {count}</span>
<button onClick={props.onAction}>Action</button>
</div>
);
};Rules for consistent JSX element formatting and structure.
const jsxFormattingRules = {
/** Enforce self-closing when JSX element has no children */
'react/self-closing-comp': ESLintRule;
/** Enforce boolean attributes notation in JSX */
'react/jsx-boolean-value': ESLintRule;
/** Enforce or forbid the use of curly braces inside JSX props */
'react/jsx-curly-brace-presence': ESLintRule;
/** Prevent missing parentheses around multilines JSX */
'react/jsx-wrap-multilines': ESLintRule;
};Usage Examples:
// ✓ Good - Self-closing components
<MyComponent />
<input type="text" />
<img src="image.jpg" alt="Description" />
// ✗ Bad - Unnecessary closing tags
<MyComponent></MyComponent>
<input type="text"></input>
<img src="image.jpg" alt="Description"></img>
// ✓ Good - Consistent boolean attribute style
// Explicit style (when configured)
<MyComponent isVisible={true} isActive={false} />
// Shorthand style (when configured)
<MyComponent isVisible isActive={false} />
// ✗ Bad - Mixed boolean styles
<MyComponent isVisible={true} isActive />
// ✓ Good - Appropriate curly brace usage
<MyComponent
title="Static String"
count={42}
isActive={isUserActive}
style={{ color: 'red' }}
/>
// ✗ Bad - Unnecessary curly braces
<MyComponent
title={"Static String"}
count={"42"}
/>
// ✓ Good - Multiline JSX with parentheses
const element = (
<div className="container">
<Header title="My App" />
<Content data={data} />
<Footer />
</div>
);
// ✗ Bad - Multiline JSX without parentheses
const element = <div className="container">
<Header title="My App" />
<Content data={data} />
<Footer />
</div>;Rules for consistent prop and attribute formatting.
const propsStyleRules = {
/** Enforce props alphabetical sorting */
'react/jsx-sort-props': ESLintRule;
/** Disallow multiple spaces between inline JSX props */
'react/jsx-props-no-multi-spaces': ESLintRule;
/** Prevent JSX prop spreading */
'react/jsx-props-no-spreading': ESLintRule;
/** Disallow JSX props to use spread operator with multiple objects */
'react/jsx-props-no-spread-multi': ESLintRule;
};Usage Examples:
// ✓ Good - Props in alphabetical order (when configured)
<MyComponent
age={25}
name="John"
onAction={handleAction}
role="admin"
/>
// ✗ Bad - Props not alphabetically sorted
<MyComponent
name="John"
age={25}
role="admin"
onAction={handleAction}
/>
// ✓ Good - Single space between props
<MyComponent prop1="value1" prop2="value2" prop3="value3" />
// ✗ Bad - Multiple spaces between props
<MyComponent prop1="value1" prop2="value2" prop3="value3" />
// ✓ Good - Explicit props (when spreading is forbidden)
<MyComponent
name={user.name}
email={user.email}
age={user.age}
/>
// ✗ Bad - Prop spreading (when forbidden)
<MyComponent {...user} />
// ✓ Good - Single spread (when spreading is allowed)
<MyComponent {...commonProps} specificProp="value" />
// ✗ Bad - Multiple spreads
<MyComponent {...props1} {...props2} />Rules for consistent naming patterns in React components.
const namingRules = {
/** Enforce PascalCase for user-defined JSX components */
'react/jsx-pascal-case': ESLintRule;
/** Enforce specific naming pattern for boolean props */
'react/boolean-prop-naming': ESLintRule;
/** Enforce event handler naming conventions in JSX */
'react/jsx-handler-names': ESLintRule;
/** Prevent missing displayName in React component definition */
'react/display-name': ESLintRule;
};Usage Examples:
// ✓ Good - Component names in PascalCase
<UserProfile />
<NavigationBar />
<DataVisualization />
// ✗ Bad - Component names not in PascalCase
<userProfile />
<navigationbar />
<dataVisualization />
// ✓ Good - Boolean props with proper naming
<Modal isOpen hasBackdrop canClose />
<Button isDisabled hasIcon />
<Input isRequired hasError />
// ✗ Bad - Boolean props without proper prefix
<Modal open backdrop close />
<Button disabled icon />
<Input required error />
// ✓ Good - Event handler naming conventions
<Button onClick={handleClick} onHover={handleHover} />
<Input onChange={handleChange} onFocus={handleFocus} />
// ✗ Bad - Event handler naming (when strict conventions enforced)
<Button onClick={click} onHover={hover} />
<Input onChange={change} onFocus={focus} />
// ✓ Good - Component with displayName
const MyComponent = () => <div>Hello</div>;
MyComponent.displayName = 'MyComponent';
export default MyComponent;Rules for organizing imports and file structure.
const fileOrganizationRules = {
/** Restrict file extensions that may contain JSX */
'react/jsx-filename-extension': ESLintRule;
/** Prevent multiple component definition per file */
'react/no-multi-comp': ESLintRule;
};Usage Examples:
// ✓ Good - JSX in appropriate file extensions
// UserProfile.jsx
export const UserProfile = ({ user }) => (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
// ✓ Good - One component per file (when rule enforces single component)
// Button.jsx
export const Button = ({ children, onClick }) => (
<button onClick={onClick}>{children}</button>
);
// ✗ Bad - Multiple components in one file (when single component enforced)
// Components.jsx
export const Button = ({ children }) => <button>{children}</button>;
export const Input = ({ value }) => <input value={value} />;
export const Label = ({ text }) => <label>{text}</label>;
// Configuration for file extensions:
{
"rules": {
"react/jsx-filename-extension": [
"error",
{ "extensions": [".jsx", ".tsx"] }
]
}
}Rules for handling styles and CSS in React components.
const styleRules = {
/** Enforce style prop value to be an object */
'react/style-prop-object': ESLintRule;
/** Forbid certain DOM props */
'react/forbid-dom-props': ESLintRule;
/** Forbid certain component props */
'react/forbid-component-props': ESLintRule;
};Usage Examples:
// ✓ Good - Style prop as object
<div style={{ color: 'red', fontSize: '16px' }}>
Styled content
</div>
// ✗ Bad - Style prop as string
<div style="color: red; font-size: 16px;">
Styled content
</div>
// ✓ Good - CSS classes (when inline styles are forbidden)
<div className="styled-content">
Content with CSS class
</div>
// ✗ Bad - Inline styles (when forbidden)
<div style={{ color: 'red' }}>
Content with inline style
</div>
// Configuration example:
{
"rules": {
"react/forbid-dom-props": ["error", {
"forbid": ["style"] // Forbid inline styles
}],
"react/forbid-component-props": ["error", {
"forbid": ["style", "className"] // Forbid styling props on custom components
}]
}
}Rules for general code formatting and whitespace.
const formattingRules = {
/** Enforce child element spacing */
'react/jsx-child-element-spacing': ESLintRule;
/** Require or prevent a new line after jsx elements and expressions */
'react/jsx-newline': ESLintRule;
/** Restrict to one expression per line in JSX */
'react/jsx-one-expression-per-line': ESLintRule;
};Usage Examples:
// ✓ Good - Proper child element spacing
<div>
<span>First element</span>
<span>Second element</span>
</div>
// ✗ Bad - Missing spacing between inline elements
<div>
<span>First</span><span>Second</span>
</div>
// ✓ Good - Newlines after JSX elements (when configured)
const MyComponent = () => {
return (
<div>
<Header />
<Content />
<Footer />
</div>
);
};
// ✓ Good - One expression per line
<div>
<span>{user.name}</span>
<span>{user.email}</span>
<span>{user.role}</span>
</div>
// ✗ Bad - Multiple expressions on same line
<div>
<span>{user.name}</span> <span>{user.email}</span>
</div>Code style rules offer extensive configuration options:
{
"rules": {
"react/sort-comp": ["error", {
"order": [
"static-variables",
"static-methods",
"instance-variables",
"lifecycle",
"everything-else",
"render"
]
}],
"react/jsx-sort-props": ["error", {
"callbacksLast": true,
"shorthandFirst": false,
"shorthandLast": true,
"ignoreCase": true,
"noSortAlphabetically": false,
"reservedFirst": true
}],
"react/function-component-definition": ["error", {
"namedComponents": "arrow-function",
"unnamedComponents": "arrow-function"
}],
"react/destructuring-assignment": ["error", "always", {
"ignoreClassFields": false,
"destructureInSignature": "always"
}],
"react/jsx-curly-brace-presence": ["error", {
"props": "never",
"children": "never",
"propElementValues": "always"
}],
"react/boolean-prop-naming": ["error", {
"rule": "^(is|has)[A-Z]([A-Za-z0-9]?)+",
"message": "Boolean props should start with 'is' or 'has'"
}]
}
}When using Prettier alongside ESLint, some formatting rules may conflict:
// .eslintrc.js
module.exports = {
extends: [
'plugin:react/recommended',
'prettier' // Prettier config should come last
],
rules: {
// Disable rules that conflict with Prettier
'react/jsx-indent': 'off',
'react/jsx-indent-props': 'off',
'react/jsx-closing-bracket-location': 'off',
'react/jsx-closing-tag-location': 'off',
'react/jsx-curly-spacing': 'off',
'react/jsx-equals-spacing': 'off',
'react/jsx-first-prop-new-line': 'off',
'react/jsx-max-props-per-line': 'off',
'react/jsx-one-expression-per-line': 'off',
'react/jsx-props-no-multi-spaces': 'off',
'react/jsx-tag-spacing': 'off',
'react/jsx-wrap-multilines': 'off',
// Keep non-formatting rules
'react/jsx-sort-props': 'error',
'react/self-closing-comp': 'error',
'react/jsx-boolean-value': 'error'
}
};