In vanilla JS I could just use formData for this, and make an Object.fromEntries() from it.
In React I wasn't sure how to do this right, so here's what I came up with after some googling around:
class App extends Component{
constructor(props){
super(props);
this.autoData = {
title:'',
description:'',
year:'',
color:'',
status:'',
price:''
}
}
handleAutoData = e => {
if (e.target.id in this.autoData) {
this.autoData[e.target.id] = e.target.value
}
}
handleAutoForm = e => {
e.preventDefault()
if (Object.keys(this.autoData).every(k => this.autoData[k])) {
this.props.addAuto(this.autoData)
}
}
render(){
...
return (
<div className="App">
<form className="form" onSubmit={this.handleAutoForm}>
<input type="text" className="form_text" placeholder="Name" id="title" onChange={this.handleAutoData} />
<input type="text" className="form_text" placeholder="Year" id="year" onChange={this.handleAutoData} />
<input type="text" className="form_text" placeholder="Price" id="price" onChange={this.handleAutoData} />
<input type="text" className="form_text" placeholder="Details" id="description" onChange={this.handleAutoData} />
<button type="submit"> Send > </button>
</form>
</div>
)
}
}
This does the job and handleAutoForm pushes the object into Redux store. However:
- Is there a better alternative for onChange event? I know it's the go-to way of handling form inputs, but right now it's spamming/overwriting my values on every keystroke. I'd only like to push a value once I stop typing/field loses focus. Out of alternatives, I saw articles of onFocusOut, but it's not supported or has issues.
- Right now I'm mutating the component's state directly. Not sure if it's critical, since I'll be pushing the state to Redux anyway. I wanted a local object inside handleAutoData, just so I could write the values into it, but every time an onChange is called, a new object is made and it overwrites the previous values. Problem is, I can't use setState because of e.target's nature - it keeps complaining about missing brackets on render, because of all the dots (when I do something like
this.setState({autoData[e.target.id]:e.target.value})). And if I assign it to a temporary variable (likelet autoKey = e.target.id), setState pushes the autoKey as key, instead of e.target.id. What could be done with this?