FakeEmpire
FakeEmpire

Reputation: 798

Making second setState in callback - bad practice?

I have a component where I am making a second setState() as a callback in the first setState(). Is this poor practice? Is there another way to call two setStates synchronously?

Initially when I called updateData() in the first setState() there was a delay in rendering the correct data in the myComponent component. It was one 'step' behind. This works, but is it conventional?

import React, { Component } from "react";
import MyComponent from "../../components/MyComponent";
import RaisedButton from "material-ui/RaisedButton";
import { generateData } from "./generateData";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      text: "",
      data: []
    };
  }

  updateData(){
    this.setState({
      data: generateData(this.state.text)
    })
  }

  handleChange(e) {
    this.setState({
      text: e.target.value
    }, () => {
      this.updateData(this.state.text)
    });
  }

  handleSubmit(e) {
    e.preventDefault();
  }

  render() {
    return (
      <div>
        <h2>Input</h2>
        <form onSubmit={e => this.handleSubmit(e)}>
          <textarea
            value={this.state.text}
            onChange={e => this.handleChange(e)}
          />
          <div>
            <RaisedButton type="submit"/>
          </div>
        </form>
        <h2>Output</h2>
        <MyComponent data={this.state.data} />
      </div>
    );
  }
}

export default App;

Upvotes: 1

Views: 324

Answers (1)

Felix Kling
Felix Kling

Reputation: 816462

The problem seems to be that you are updating data from this.state.text. Instead you can update both text and data in a single call by referencing the original input value:

handleChange(e) {
  this.setState({
    text: e.target.value,
    data: generateData(e.target.value),
  });
}

This is certainly preferred over making two calls to setState (which implies potentially rerender the component twice).

Upvotes: 5

Related Questions