onKeyUp not working in React where onChange did

Cdhippen picture Cdhippen · Jul 12, 2018 · Viewed 9.4k times · Source

I'm doing a React coding challenge that requires a value to be updated onKeyUp. I initially set it to update onChange but the tests require onKeyUp so I tried to change it to that, but my fields are no longer updating and I can't type anything into the textarea.

class MarkdownApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ''
    };

    this.handleKeyUp = this.handleKeyUp.bind(this);
  }

  handleKeyUp(event) {
    this.setState({ value: event.target.value })
  }

  render() {
    return (
      <form>
        <label>
          Enter your markdown here:
          <br />
          <textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
          <br />
        </label>
        <label>
          Your markup will be previewed here:
          <p id='preview'>{marked(this.state.value)}</p>
        </label>
      </form>
    );
  }
}

ReactDOM.render(
  <MarkdownApp />,
  document.getElementById('root')
);

Like I said, this worked fine when it was onChange and my function was handleChange, but since I switched it I can't type anything.

Answer

duhaime picture duhaime · Jul 12, 2018

I would just remove the value attribute from the textarea. Because if you put the value attribute to it then the user won't be able to change it interactively. The value will always stay fixed(unless you explicitly change the value in your code). You don't need to control that with React--the DOM will hold onto the value for you.

The only change I've made below is to remove value={this.state.value} from the textarea element:

import React from 'react';
import ReactDOM from 'react-dom';

class MarkdownApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ''
    };

    this.handleKeyUp = this.handleKeyUp.bind(this);
  }

  handleKeyUp(event) {
    this.setState({ value: event.target.value })
  }

  render() {
    return (
      <form>
        <label>
          Enter your markdown here:
          <br />
          <textarea value={this.state.value} onKeyUp={this.handleKeyUp} id='editor' />
          <br />
        </label>
        <label>
          Your markup will be previewed here:
          <p id='preview'>{this.state.value}</p>
        </label>
      </form>
    );
  }
}

ReactDOM.render(
  <MarkdownApp />,
  document.getElementById('root')
);