The moment when i start typing on my textarea input, it becomes undefined undefined undefined. The name field is updating the state but the address field didn't. So how to update the address state from onChange event handler?
constructor(){
super();
this.state = {
users: {
name: '',
address: '',
},
}
this.getOneUser = this.getOneUser.bind(this);
this.onChangeHandler = this.onChangeHandler.bind(this);
this.onSubmitHandler = this.onSubmitHandler.bind(this);
}
async getOneUser(){
try{
const {id} = this.props.match.params;
const res = await fetch(`http://localhost:3003/users/${id}`);
const data = await res.json();
const {name, address} = data;
this.setState({users: {name, address}}, () => console.log(this.state));
}catch(err){
console.error(err.message);
}
}
async onSubmitHandler(e){
e.preventDefault();
const {id} = this.props.match.params;
const {history} = this.props.match;
try{
const res = await fetch(`http://localhost:3003/users/${id}`, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(this.state.users)
});
if(!res.ok) throw new Error(`could not fetch`);
const data = await res.json();
this.props.history.push('/');
}catch(err){
console.error(`${err.message}`);
}
}
onChangeHandler(e){
const {name, value} = e.target;
this.setState({
users: {...this.state.users, [name]:value}
});
};
render(){
const addr = this.state.users.address;
return <div>
<input type='text' name='name' value={this.state.users.name} onChange={e => this.onChangeHandler(e)} className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" />
<textarea name='address' value={`${addr.street}, ${addr.city}, ${addr.zipcode}`} onChange={e => this.onChangeHandler(e)} className="form-control" placeholder="Address" id="floatingTextarea">
</textarea>
</div>
CodePudding user response:
You can handle the address case separately in onChangeHandler
. You can map the first three comma-separated values to your address
object and ignore others.
onChangeHandler(e) {
const { name, value } = e.target;
if (name === "address") {
const [street = "", city = "", zipcode = ""] = value.split(",");
this.setState({
users: {
...this.state.users,
[name]: {
street: street.trim(),
city: city.trim(),
zipcode: zipcode.trim()
}
}
});
} else {
this.setState({
users: { ...this.state.users, [name]: value }
});
}
}
Remove the value you have set and give an informative placeholder.
<textarea
name="address"
onChange={(e) => this.onChangeHandler(e)}
className="form-control"
placeholder="street, city, zipcode"
id="floatingTextarea"
></textarea>
Code sandbox => https://codesandbox.io/s/eager-frog-snv8t?file=/src/App.js