I am trying to set the state of features, which is an array, based on inputs into textarea. I am having no luck setting the state of features. When I press one key, that key becomes the next index value in the state. If I hit another key, that key becomes the next index value in the state. So if I manually set my initial state of features to features: ["First", "Second", "Third"],
, the result will be features: ["First", "Second", "Third", "Firstf" , "Firstd"]
if I hit f and then d
The relevant State
class CreateItem extends Component {
state = {
features: [""],
};
This is how I am attempting to create textarea's based on the state
<label htmlFor="features">
Features
{this.state.features.map((feature, i) => (
<div key={i}>
<textarea
key={i}
type="features"
placeholder={`${feature}`}
name={`features.${i}`}
value={this.state.features[`${i}`]}
onChange={this.handleFeatureArrayChange}
onKeyDown={this.keyPress}
/>
</div>
))}
</label>
Here is the handleChange
handleFeatureArrayChange = e => {
const { name, type, value } = e.target;
this.setState(prevState => ({
[name]: [...prevState.features, value]
}));
};
This is how I am attempting to create new textarea's each time the user hits enter:
keyPress = e => {
if (e.keyCode == 13) {
this.setState({
features: this.state.features.concat("")
});
}
};
The problem is you're just appending to state each time a key is pressed.
handleFeatureArrayChange = e => {
const { name, type, value } = e.target;
this.setState(prevState => ({
[name]: [...prevState.features, value] // this is effectively the same as .concat(value)
}));
};
You want to update the value at the current index. Try changing the name of the input to just be key
and then mapping instead
handleFeatureArrayChange = e => {
const { name, type, value } = e.target;
this.setState(prevState => ({
features: prevState.features.map((feat, key) => {
if (key == name) {
return value
} else
return feat;
}
)
}));
};