react/destructuring-assignment

Enforce one style for reading props, state, and context: destructured or not

fixable

Some components read props.name, and others destructure { name } first. With destructuring, the top of a component lists everything it uses. Without it, you always see where a value comes from. This rule makes your codebase stick to one style.

By default it asks for destructuring, in function components (props, context) and in class components (this.props, this.state, this.context).

--fix only works for destructureInSignature. It moves the destructuring into the parameter list.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"react/destructuring-assignment" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"react/destructuring-assignment" = [
  "error",
  "always", # "always" or "never"
  {
    ignoreClassFields = false,
    destructureInSignature = "ignore", # "always" or "ignore"
  },
]

Examples#

example.jsx2 problems
function Badge(props) {
  return <span className={props.color}>{props.label}</span>;
}
example.jsx1 problem
class Counter extends React.Component {
  render() {
    return <output>{this.state.count}</output>;
  }
}
example.jsxNo problems
function Badge({ color, label }) {
  return <span className={color}>{label}</span>;
}

class Counter extends React.Component {
  render() {
    const { count } = this.state;
    return <output>{count}</output>;
  }
}

Passing the whole object on is fine:

example.jsxNo problems
function Badge(props) {
  return <span {...props} />;
}

Options#

bunfig.toml
[lint.rules]
"react/destructuring-assignment" = ["error", "always", {
  destructureInSignature = "always",
}]

The first option is "always" (default) or "never". With "never", the rule reports destructuring instead:

example.jsxwith "never"1 problem
function Badge({ color, label }) {
  return <span className={color}>{label}</span>;
}

The second option is an object. Both keys only matter with "always":

OptionDefaultWhat it does
ignoreClassFieldsfalseAllow this.props.x in a class field.
destructureInSignature"ignore""always" reports const { x } = props in the body of a function component, unless props is also used somewhere else.
example.jsxwith "always", { "ignoreClassFields": true }No problems
class Counter extends React.Component {
  state = { count: this.props.start };
  render() {
    const { count } = this.state;
    return <output>{count}</output>;
  }
}
example.jsxwith "always", { "destructureInSignature": "always" }1 problem
function Badge(props) {
  const { color, label } = props;
  return <span className={color}>{label}</span>;
}