Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent direct mutation of this.state (react/no-direct-mutation-state) #1571

Closed
feross opened this issue Oct 28, 2020 · 1 comment
Closed

Comments

@feross
Copy link
Member

feross commented Oct 28, 2020

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md

NEVER mutate this.state directly, as calling setState() afterwards may replace
the mutation you made. Treat this.state as if it were immutable.

The only place that's acceptable to assign this.state is in a ES6 class component constructor.

Rule Details

This rule is aimed to forbid the use of mutating this.state directly.

Examples of incorrect code for this rule:

var Hello = createReactClass({
  componentDidMount: function() {
    this.state.name = this.props.name.toUpperCase();
  },
  render: function() {
    return <div>Hello {this.state.name}</div>;
  }
});

class Hello extends React.Component {
  constructor(props) {
    super(props)

    // Assign at instance creation time, not on a callback
    doSomethingAsync(() => {
      this.state = 'bad';
    });
  }
}

Examples of correct code for this rule:

var Hello = createReactClass({
  componentDidMount: function() {
    this.setState({
      name: this.props.name.toUpperCase();
    });
  },
  render: function() {
    return <div>Hello {this.state.name}</div>;
  }
});

class Hello extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      foo: 'bar',
    }
  }
}
@ungoldman
Copy link
Contributor

ungoldman commented Mar 4, 2021

Hi, I just ran into this error while working on a non-react project.

Unfortunately this rule applies to anything mutating something that looks like this.state, even when it's not in a react context at all. In my case it's in a choo context, where mutating state is conversely the norm and expected, and there is no setState method.

What this means is this rule is unilaterally enforcing a react convention for all code that looks similar, even when it shouldn't apply at all. I'm pegging standard to 15 for now -- I don't want to have to write eslint-disable-rule in possibly hundreds of component files.

Hoping there's a reasonable compromise here -- alternately we can eject and modify standard eslint rules ourselves, but I'd prefer to remain on the good ship standard.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Archived in project
Development

No branches or pull requests

2 participants