woojoo666
woojoo666

Reputation: 7921

React TextArea value not automatically updating as expected

So I was playing around in React and tried to make an app where you can display and modify any property in the component state, from the component itself. Basically, you enter a key (eg "foo"), and then the app will load the current value at that key (eg this.state["foo"]) into a textarea, where you can modify the value.

Here is the sandbox: https://codesandbox.io/s/twilight-bird-6z6cx And here is the code used in the sandbox:

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

import "./styles.css";

class App extends React.Component {
  state = {
    inputVal: ""
  };
  onKeyInputChange(e) {
    this.setState({ key: e.target.value });
  }
  onValInputChange(e) {
    this.setState({ [this.state.key]: e.target.value });
  }
  render() {
    return (
      <div className="App">
        <div>
          key: <input onChange={this.onKeyInputChange.bind(this)} />
        </div>
        <div>
          value:
          <textarea
            onChange={this.onValInputChange.bind(this)}
            value={this.state[this.state.key]}
          />
        </div>
        <h2>key: {this.state.key}</h2>
        <h2>value: {this.state[this.state.key]}</h2>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Notice how the <textarea>'s value and the <h2>'s value are both set to this.state[this.state.key], so they should always show the same value. However, if you change the text value at say, key "foo", and then change to key "fooo", the h2's value will change but not the textarea. To put it more clearly:

  1. type "foo" into the key input field
  2. type "hello world" into the textarea
  3. type "fooo" into the key input field
  4. notice how the <h2>'s value is now blank, but the textarea still shows "hello world"

Upvotes: 4

Views: 5125

Answers (3)

Adnan Saify
Adnan Saify

Reputation: 36

If you do console this.state[this.state.key] you can see the undefined is being returned and if undefined is returned react does not know that what happened with your input and hence it does not update the textArea value.It is recommended to always pass an empty string instead of an undefined value.

similar issue discussion on github -> https://github.com/facebook/react/issues/6222#issuecomment-194061477

Try to use arrow function , you do not need to bind the functions.

Working Example sandbox

Upvotes: 1

Dacre Denny
Dacre Denny

Reputation: 30360

To resolve this issue, make sure that you're passing a "non-undefined" value to the textareas value prop which will cause the textarea element to update as expected.

A simple solution would be to pass an empty string for value in the undefined case which can be done like this this.state[this.state.key] || "":

<textarea onChange={this.onValInputChange.bind(this)} 
          value={this.state[this.state.key] || ""} />

Here's a working codesandbox

Upvotes: 7

Joseph D.
Joseph D.

Reputation: 12174

If this.state[this.state.key] is undefined the controlled input (textarea) becomes editable.

This would mean that the value from the previous render will be retained.

You can play around with these conditions to prove:

// editable - value is retained
value={this.state.key === "foo" ? this.state[this.state.key] : null} 

// non-editable
value={this.state.key === "foo" ? this.state[this.state.key] : ""}

So to fix this, assign an empty string when this.state[this.state.key] is undefined.

<textarea
  onChange={this.onValInputChange.bind(this)}
  value={this.state[this.state.key] || ""} // if undefined, an empty string will be supplied
/>

Upvotes: 2

Related Questions