Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get "Use callback in setState when referencing the previous state"?

I'm learning React and I have ESLint installed in my project. It started giving me errors like:

Use callback in setState when referencing the previous state react/no-access-state-in-setstate

In my React component I have a constructor:

  constructor() {
    super()
    this.state = {
      currentIdVehicle: null,
      currentIdModel: null,
      currentIdVehicleFinal: null,
      marca: [],
      veiculo: [],
      modeloEAno: [],
      vehicleFinal: [],
      infoTable: [],
    };
  }

In my function I have:

  getMarca = () => {
    this.setState({ marca: [], veiculo: [], modeloEAno: [] });
    api.get(`/marcas.json`).then(res => {
      res.data.map((item) => {
        const joined = this.state.marca.concat([
          { name: item.name, id: item.id },
        ]);
        this.setState({ marca: joined });
      });
    });
  };

I understand that it is not correct to use this.state within setState, but how can I resolve this error?

like image 571
Felipe Noka Avatar asked Jun 22 '19 17:06

Felipe Noka


People also ask

Why do we use callbacks in setState?

The setState function takes an optional callback parameter that can be used to make updates after the state is changed. This function will get called once the state has been updated, and the callback will receive the updated value of the state.

Can you setState in a setState callback?

Yes, you can call setState() within the callback of another setState() .

What is the second argument in setState?

The second argument that can optionally be passed to setState is a callback function which gets called immediately after the setState is completed and the components get re-rendered.

What happens when call setState?

The setState() schedule changes to the component's state object and tells React that the component and its children must rerender with the updated state: // Correct this.


1 Answers

Instead of this:

      res.data.map((item) => {
        const joined = this.state.marca.concat([
          { name: item.name, id: item.id },
        ]);
        this.setState({ marca: joined });
      });

Do this:

      res.data.map((item) => this.setState(prevState => {
        const joined = prevState.marca.concat([
          { name: item.name, id: item.id },
        ]);
        return({ marca: joined });
      }));

You're not supposed to directly or indirectly reference this.state in what you eventually pass to this.setState.

like image 135
Joseph Sible-Reinstate Monica Avatar answered Nov 12 '22 12:11

Joseph Sible-Reinstate Monica