Reputation: 14926
I am trying to get functionality where a drop down option can be selected and a text area matches it's text to that option.
So if I select option 1 then type, select option 2 it is clear so I type something else. Now if I switch between option 1 & 2 I can see the text I typed for each option.
I have bound the value of the textarea to an object property data[selected]
but when this state value updates the text area does not update. What did I do wrong?
Here is my code:
(code sandbox: https://codesandbox.io/s/hardcore-fog-3pibo?file=/src/App.jsx)
import React, { useState, useEffect } from "react";
import "./styles.css";
export default function App() {
const parentData = ["one", "two", "three"];
const [selected, setSelected] = useState("two");
const [data, setData] = useState(
parentData.reduce((a, b) => ((a[b] = ""), a), {})
);
function handleSelect(event) {
setSelected(event.target.value);
}
function handleTextChange(event) {
let val = event.target.value;
setData((prev) => {
prev[selected] = val;
return prev;
});
console.log(data[selected]);
console.log(selected);
console.log(val);
}
return (
<div className="App">
<h1>Selected is: {selected}</h1>
<select value={selected} onChange={handleSelect} name="" id="">
{parentData.map((val, i) => {
return (
<option key={i} value={val}>
{val}
</option>
);
})}
</select>
<br /> <br />
<textarea
onChange={handleTextChange}
value={data[selected]}
name="data"
id=""
cols="30"
rows="10"
></textarea>
{console.log("parent render")}
</div>
);
}
Upvotes: 1
Views: 384
Reputation: 3
Yash Joshi's answer was perfect, except my solution was in class form. So that my
<textarea value={this.state.myText} onChange={this.changeMyText} />
Would not be changed by
someOtherFunction(){
this.setState({
myText: this.state.myText + "abcde"
});
}
And instead the solution was to change this to
someOtherFunction(){
let newtext = this.state.myText + "abcde";
this.setState({
myText: newtext;
});
}
But surreal enough is that this solution isn't required for just regular <input/>
s
Upvotes: 0
Reputation: 106
You need to use the spread operator, this way, you will add the new value, and not mutate the state.
function handleTextChange(event) {
let val = event.target.value;
setData(data => ...data, val)
}
Upvotes: 0
Reputation: 2784
In handleTextChange
you are mutating the object. Try doing the below:
setData((prev) => {
return {
...prev,
[selected]: val
};
});
Upvotes: 2