I'm trying to experiment with React, I have a issue of updating state values of a particular key.
Here is my state
this.state = {
connections : {
facebook : "http://facebook.com",
flickr : null,
foursquare : null,
googleplus : null,
id : 0,
instagram : "http://instagram.com/",
openstreetmap : null,
pinterest : null,
place_id : 1,
tomtom : null,
tripadvisor : null,
twitter : "http://twitter.com",
vimeo : null,
wikipedia : null,
yelp : null,
youtube : null
},
contact : {
}
}
I'm calling a external component and sending parameters to it.
<Connection type="Facebook" icon={facebookIcon} placeholder="Add Facebook Link" name="facebook" value={this.state.connections.facebook} onChange={this.handleChange.bind(this)}/>
<Connection type="Twitter" icon={twitterIcon} placeholder="Add Twitter Link" name="twitter" value={this.state.connections.twitter} onChange={this.handleChange.bind(this)}/>
<Connection type="Instagram" icon={instagramIcon} placeholder="Add Instagram Link" name="instagram" value={this.state.connections.instagram} onChange={this.handleChange.bind(this)}/>
Component in external file:
<input type="text" name={this.props.name} placeholder={this.state.placeholder} value={this.props.value} onChange={this.props.onChange} />
On change of value in textbox,
handleChange(e) {
this.setState({
connections : {[e.target.name]: e.target.value}
})
}
While I try to change any field values, it sets the rest 2 with empty. For example, if I try to edit textbox of Facebook, it sets Twitter and Instagram values to empty.
May I know what I'm doing wrong in setting handleChange? I'm sure its something wrong with this.setState, but not sure how to target particular key value.
Give it a value. Create another method inside the class and update the state of the component using 'this. setState()' method. Pass the state object in a JSX element and call the method to update the state on a specific event like button click.
state , we use this. setState() . This is a function available to all React components that use state, and allows us to let React know that the component state has changed. This way the component knows it should re-render, because its state has changed and its UI will most likely also change.
React will then look at the virtual DOM, it also has a copy of the old virtual DOM, that is why we shouldn't update the state directly, so we can have two different object references in memory, we have the old virtual DOM as well as the new virtual DOM.
In React, the state is immutable. In simple terms it means that you should not modify it directly.
You should actually rather use
handleChange(e) {
this.setState(oldState => ({
connections: {[e.target.name]: e.target.value, ...oldState.connections},
}));
}
because otherwise you might overwrite state-changes that have not been applied yet.
see https://reactjs.org/docs/state-and-lifecycle.html
setState
performs a shallow merge instead of a deep one (more explanation in the docs), so you're completely overwriting all of connections
with just your one value. If you want to keep the other keys in connections
intact, you can change handleChange
to this:
handleChange(e) {
this.setState({
connections : {...this.state.connections, [e.target.name]: e.target.value}
})
}
This will shallow copy all of this.state.connections
, and then set e.target.name
over top of it.
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