1

I have 2 examples, one with class component and one with function component doing exactly the same thing. Im using react 16.13.1. I know that if you dont persist the event you will get an error saying that the event target is null. This happens as expected in class component. In function component though, this isnt the case. What is the difference between them?

export class App extends React.Component {
  constructor() {
    super();
    this.state = { text: '' };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    console.log(event.target.value);
    this.setState(() => ({
      text: event.target.value
    }));
  }
  render() {
    return (
      <div>
        <span>Text: </span>
        <input onChange={this.handleChange} value={this.state.text} />
      </div>
    );
  }
}


const App = () => {
  const [state, setState] = useState({ text: "" });
  const handleChange = (event) => {
    console.log(event.target.value);
    setState({
      text: event.target.value,
    });
  };

  return (
    <div>
      <span>Text: </span>
      <input onChange={handleChange} value={state.text} />
    </div>
  );
};
Nick
  • 2,818
  • 5
  • 42
  • 60

1 Answers1

1

This all comes down to the timing for when this.setState() and setState() is called. In your class component, the additional arrow function declaration inside this.setState causes an additional delay that makes the call take longer than the useState hook in the functional component. If you wrap the setState() call in your functional component with a setTimeout of 100, you get an error as expected. Also, if you modify the setState call to this.setState({ text: event.target.value }) in your class-based component, you no longer get an error. Finally figured that out with some inspiration from the official React docs.

gloo
  • 681
  • 2
  • 12
  • Indeed it works as you. But inside the setTimeout: console.log(event.target.value); setTimeout(() => { console.log(event.target.value); // Works }, 1000); console prints an empty value. Shouldnt be what i wrote in the input? – Nick May 26 '22 at 19:55
  • That is because your input is a controlled component, and if you are not updating your state in `handleChange`, then your input value will reset to the initial state `""`, and that is being logged. – gloo May 26 '22 at 20:39