Skip to content

react/no-unused-prop-types on setState #1558

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

Closed
ardok opened this issue Nov 21, 2017 · 5 comments
Closed

react/no-unused-prop-types on setState #1558

ardok opened this issue Nov 21, 2017 · 5 comments

Comments

@ardok
Copy link

ardok commented Nov 21, 2017

My component doesn't have any this.state.
The lint cannot detect that I'm actually using the state inside setState from prevState argument.
But it says that:
error Unused state field: 'updateQueue' react/no-unused-state

class Component extends Component <{}, {updateQueue: Array<string>}> {
  ...
  debouncedUpdate = debounce((cellsetId, options) => {
    this.setState((prevState, props) => {
      const {updateQueue} = prevState;
      const {updateCells} = props;
      updateCells(cellsetId, updateQueue, options);
      return {
        updateQueue: [],
      };
    });
  }, 2000);
  ...
}
@ljharb
Copy link
Member

ljharb commented Nov 21, 2017

it seems like the debounce is the issue.

In general, you shouldn't have arrow functions in class properties anyways; try this instead (it will be much more performant and lintable and much more importantly, more testable):

debouncedUpdate = debounce(this.update.bind(this), 2000);
update(cellsetId, options) {
  this.setState((prevState, props) => {
    const {updateQueue} = prevState;
    const {updateCells} = props;
    updateCells(cellsetId, updateQueue, options);
    return {
      updateQueue: [],
    };
  });
}

@ardok
Copy link
Author

ardok commented Nov 21, 2017

It's still giving me the error even using your suggestion.
Not really the debounce though, you can even do this:

function updateFoo(selectedIds) {
  return null;
}

class Test extends Component<{}, {selectedIds: Array<string>}> {
  constructor(props: *) {
    super(props);
    this.state = {
      selectedIds: [],
    };
  }

  onChange = (item: {id: string}) => {
    const {id} = item;
    this.setState((prevState, props) => {
      const {selectedIds} = prevState;
      selectedIds.push(id);
      updateFoo(selectedIds);
      this.setState({
        selectedIds: [],
      });
    });
  };

  render() {
    return (
      <div>
        <select onChange={() => this.onChange({id: '1'})}>
          <option value='1'>1</option>
        </select>
      </div>
    );
  }
}

And it will still complain about the no-unused-state.
I think at the moment, it could only mark it as ok as long as it sees something from this.state.

And regarding the arrow functions, yeah, I read some articles about that.
But it's just so much more convenient doing () => rather than having all the methods in constructor and doing this.method = this.method.bind(this); every time.

@kaiyoma
Copy link

kaiyoma commented Jan 15, 2018

I'm also running into this. I set some state (in componentWillMount) and the only place it gets accessed is inside a setState callback updater, which references prevState, not this.state, which appears to be confusing this rule. Checking only for instances of this.state.foo is not enough to determine conclusively that foo isn't being used.

@Titozzz
Copy link

Titozzz commented Feb 1, 2018

Same thing here using functional setState

@battaile
Copy link

battaile commented May 17, 2018

actually never mind, got a workaround for my specific case

@ljharb ljharb closed this as completed in 06bbf28 Feb 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

5 participants