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:
key
input fieldkey
input field<h2>
's value is now blank, but the textarea still shows "hello world"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
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
/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With