title: How to debounce a controlled input?
body: <p>I'm currently struggling with react inputs and debounce from lodash.
  Most of the time when I have a form I also have an edit option, so I need a controlled component to fill back the inputs using <code>value={state["targetValue"]}</code> so I can fill and edit the field.</p>
  
  <p>However, if the component is controlled debounce isn't working.
  I made a simple example on CodeSandbox: <a href="https://codesandbox.io/embed/icy-cloud-ydzj2?fontsize=14&amp;hidenavigation=1&amp;theme=dark" rel="noreferrer">https://codesandbox.io/embed/icy-cloud-ydzj2?fontsize=14&amp;hidenavigation=1&amp;theme=dark</a></p>
  
  <p>Code: </p>
  
  <pre><code>import React, { Component } from "react";
  import ReactDOM from "react-dom";
  import { debounce } from "lodash";
  
  import "./styles.css";
  
  class App extends Component {
    constructor(props) {
      super(props);
      this.state = {
        name: "",
        title: "",
        editMode: false
      };
      this.debouncedEvent = React.createRef();
    }
  
    debounceEvent(_fn, timer = 500, options = null) {
      this.debouncedEvent.current = debounce(_fn, timer, options);
      return e =&gt; {
        e.persist();
        return this.debouncedEvent.current(e);
      };
    }
  
    componentWillUnmount() {
      this.debouncedEvent.current.cancel();
    }
  
    onChangeValue = event =&gt; {
      const { name, value } = event.target;
  
      this.setState(() =&gt; {
        return { [name]: value };
      });
    };
  
    onRequestEdit = () =&gt; {
      this.setState({ name: "Abla blabla bla", editMode: true });
    };
  
    onCancelEdit = () =&gt; {
      if (this.state.editMode) this.setState({ name: "", editMode: false });
    };
  
    onSubmit = event =&gt; {
      event.preventDefault();
      console.log("Submiting", this.state.name);
    };
  
    render() {
      const { name, editMode } = this.state;
      const isSubmitOrEditLabel = editMode ? `Edit` : "Submit";
      console.log("rendering", name);
      return (
        &lt;div className="App"&gt;
          &lt;h1&gt; How to debounce controlled input ?&lt;/h1&gt;
          &lt;button type="button" onClick={this.onRequestEdit}&gt;
            Fill with dummy data
          &lt;/button&gt;
          &lt;button type="button" onClick={this.onCancelEdit}&gt;
            Cancel Edit Mode
          &lt;/button&gt;
          &lt;div style={{ marginTop: "25px" }}&gt;
            &lt;label&gt;
              Controlled / Can be used for editing but not with debounce
            &lt;/label&gt;
            &lt;form onSubmit={this.onSubmit}&gt;
              &lt;input
                required
                type="text"
                name="name"
                value={name}
                placeholder="type something"
                // onChange={this.onChangeValue}
                onChange={this.debounceEvent(this.onChangeValue)}
              /&gt;
              &lt;button type="submit"&gt;{isSubmitOrEditLabel}&lt;/button&gt;
            &lt;/form&gt;
          &lt;/div&gt;
          &lt;div style={{ marginTop: "25px" }}&gt;
            &lt;label&gt; Uncontrolled / Can't be used for editing &lt;/label&gt;
            &lt;form onSubmit={this.onSubmit}&gt;
              &lt;input
                required
                type="text"
                name="name"
                placeholder="type something"
                onChange={this.debounceEvent(this.onChangeValue)}
              /&gt;
              &lt;button type="submit"&gt;{isSubmitOrEditLabel}&lt;/button&gt;
            &lt;/form&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      );
    }
  }
  
  const rootElement = document.getElementById("root");
  ReactDOM.render(&lt;App /&gt;, rootElement);
  </code></pre>