title: React input onChange lag
body: <p>I have a simple controlled input with an <code>onChange</code> event handler. </p>
  
  <p>Everything works as it should with <code>handleChange</code> firing on every keystroke, the problem is it is <strong>very slow</strong>. </p>
  
  <p>There is a <em>very</em> noticeable lag when using the input. Is there some extra code I have to right to get this to work like a normal input? </p>
  
  <p>Do I have to <em>debounce</em> the input? </p>
  
  <p>There is no mention of this issue in the docs as far as I can tell, and I don't know if there's something extra I have to do or if I'm using the <code>onChange</code> callback incorrectly.</p>
  
  <pre><code>handleChange = (event) =&gt; {
      this.setState({ itemNumber: event.target.value })
    }
  
  
  &lt;TextField
        id="Part #"
        label="Part #"
        value={this.state.itemNumber}
        onChange={this.handleChange}
        margin="normal"
      /&gt;
  </code></pre>
  
  <h2>The component:</h2>
  
  <pre><code>export class Dashboard extends Component {
    state = {
      report: '',
      selectedDate: new Date(),
      itemNumber: '',
    }
  
    static propTypes = {
      classes: object,
      headerTitle: string,
      userInfo: object,
    }
  
    static defaultProps = {
      classes: {},
      headerTitle: undefined,
      userInfo: {},
    }
  
    reportSelected = (event) =&gt; {
      this.setState(() =&gt; {
        return {
          report: event.target.value,
        }
      })
    }
  
    handleDateChange = (date) =&gt; {
      this.setState({ selectedDate: new Date(date) })
    }
  
    handleChange = (event) =&gt; {
      this.setState({ itemNumber: event.target.value })
    }
  
    render () {
      const { classes, headerTitle, userInfo } = this.props
      return (
        &lt;div className={classes.dashboard}&gt;
          &lt;HeaderTitle title="Dashboard" /&gt;
          &lt;Helmet&gt;
            &lt;title&gt;{headerTitle}&lt;/title&gt;
          &lt;/Helmet&gt;
  
          { userInfo.isAuthorized &amp;&amp;
            &lt;Grid container direction={'row'} justify={'center'} className={classes.formContainer}&gt;
              &lt;Grid item xs={12} sm={12} md={12} lg={6} xl={5}&gt;
                &lt;form className={classes.form}&gt;
                  &lt;FormControl className={classes.presetReportsInput}&gt;
                    &lt;InputLabel htmlFor="reports"&gt;Preset Reports&lt;/InputLabel&gt;
                    &lt;Select
                      value={this.state.report}
                      onChange={this.reportSelected}
                    &gt;
                      &lt;MenuItem value=""&gt;
                        &lt;em&gt;None&lt;/em&gt;
                      &lt;/MenuItem&gt;
                      {presetReports.getReportList().map(report =&gt; (
                        &lt;MenuItem value={report.name} key={report.name}&gt;
                          {report.name}
                        &lt;/MenuItem&gt;
                      ))}
                    &lt;/Select&gt;
                  &lt;/FormControl&gt;
  
                  { (this.state.report === 'Inventory Snapshot' ||
                     this.state.report === 'Weekly Fill Rate' ||
                     this.state.report === 'Open Orders' ||
                     this.state.report === 'Weekly Shipments') &amp;&amp;
                     &lt;div&gt;
                       &lt;Grid container spacing={8} direction={'row'}&gt;
                         &lt;Grid item&gt;
                           &lt;MuiPickersUtilsProvider utils={MomentUtils}&gt;
                             &lt;DatePicker
                               className={classes.datePicker}
                               margin="normal"
                               keyboard
                               format="DD/MM/YYYY"
                               disableFuture
                               autoOk
                               mask={value =&gt; (value ? [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/] : [])}
                               value={this.state.selectedDate}
                               onChange={this.handleDateChange}
                               disableOpenOnEnter
                               animateYearScrolling={false}
                             /&gt;
                           &lt;/MuiPickersUtilsProvider&gt;
                         &lt;/Grid&gt;
  
                         &lt;Grid item&gt;
                           &lt;TextField
                             id="Part #"
                             label="Part #"
                             value={this.state.itemNumber}
                             onChange={this.handleChange}
                             margin="normal"
                           /&gt;
                         &lt;/Grid&gt;
                       &lt;/Grid&gt;
  
                       &lt;Button variant="raised" color="primary" style={{ marginTop: 10 }}&gt;
                         Search
                       &lt;/Button&gt;
                     &lt;/div&gt;
                  }
  
                  { this.state.report === '' &amp;&amp;
                    &lt;div&gt;
                      &lt;TextField
                        id="queryField"
                        label="Run a Query"
                        className={classes.queryField}
                        helperText=""
                        margin="normal"
                        multiline
                        rows="5"
                      /&gt;
  
                      &lt;Grid container direction={'row'} justify={'flex-end'}&gt;
                        &lt;Grid item&gt;
                          &lt;Button variant="raised" color="primary"&gt;
                            Export
                          &lt;/Button&gt;
                        &lt;/Grid&gt;
                        &lt;Grid item&gt;
                          &lt;Button variant="raised" color="primary"&gt;
                            Save Query
                          &lt;/Button&gt;
                        &lt;/Grid&gt;
                      &lt;/Grid&gt;
                    &lt;/div&gt;
                  }
                &lt;/form&gt;
              &lt;/Grid&gt;
  
              { this.state.report === 'Inventory Snapshot' &amp;&amp;
                &lt;Grid container className={classes.table}&gt;
                  &lt;Grid item xs={12} sm={12} md={12} lg={12} xl={12}&gt;
                    &lt;InventoryReport /&gt;
                  &lt;/Grid&gt;
                &lt;/Grid&gt;
              }
            &lt;/Grid&gt;
          }
        &lt;/div&gt;
      )
    }
  }
  
  const styles = {
    dashboard: {},
    formContainer: {
      margin: 0,
      width: '100%',
    },
    presetReportsInput: {
      width: '100%',
      margin: '20% 0 0 0',
    },
    queryField: {
      width: '100%',
      margin: '20% 0 0 0',
    },
    table: {
      margin: '50px 0 10px 0',
    },
    datePicker: {
      marginTop: 32,
    },
  }
  
  const mapStateToProps = state =&gt; {
    const { layout } = state
    const { headerTitle } = layout
    return {
      headerTitle: headerTitle,
    }
  }
  
  export default connect(mapStateToProps)(withStyles(styles)(Dashboard))
  </code></pre>
  
  <p>I'm watching the state update in react devtools in chrome and there's at least a 500ms lag between a character being entered and the state updating, much longer for faster typing. Why is setState so slow? What's the workaround to getting this form to behave like a normal web form?</p>