Reputation: 73
I have one component from where user can route to form. There are two options: create an new form or edit old one. I send all data with Link location to that form component. But because I have more than 8 fields, it gets messy to verify if location state exists or if there is no location state, use default values.
Currently I have something like that:
this.state = {
firstName: this.props.location.state !== undefined ?
this.props.location.state.userProfile.firstName : '',
familyName: this.props.location.state !== undefined ?
this.props.location.state.userProfile.familyName : '',
address: this.props.location.state !== undefined ?
this.props.location.state.userProfile.address : 'Enter your address',
city: this.props.location.state !== undefined ?
this.props.location.state.userProfile.city : 'Select your city',
country: this.props.location.state !== undefined ?
this.props.location.state.userProfile.country : 'Select your country',
field: this.props.location.state !== undefined ?
this.props.location.state.userProfile.field : '',
message: this.props.location.state !== undefined ? 'Save my changes' : 'Create'
}
And this is received like that:
<Link to={{
pathname: '/register/create', state: {
userProfile: item <--comes from mapping
}
}}>
Is there any better way to achieve it? Maybe just set main object as state and then setState's fields inside that one object?
Also using Context could be option, but as I read it shouldn't be used for just passing props to child's?
Upvotes: 0
Views: 203
Reputation: 3731
I would rather deconstruct the object and have a default object in the case of any data
// this could be even outside of your class.
const defaultObj = {
firstName: '',
familyName: '',
address: 'Enter your address',
city: 'Select your city',
country: 'Select your country',
field: '',
}
/* the constructor*/
constructor(){
const { userProfile = {} } = this.props.location.state || {};
this.state = {
...defaultObj
...userProfile
}
}
Upvotes: 1
Reputation: 387
The "select your city" shouldn't be in your state. It's better to just leave it empty and pass it to the form as {state.city || "select your city"}
JS:
if (this.props.location.state) {
const {firstName, familyName, address, country, field} = this.props.location.state.userProfile;
this.setState({firstName, familyName, address, country, field, message = 'Save my changes'})
}
JSX (view):
<p>City: {state.city || "select your city"}</p>
<p>Message: {state.message || 'Create'}</p>
Upvotes: 0
Reputation: 371
At least a point that is possible to simplify: in location.state
stores an object and the local state can be filled from it directly:
this.state = this.props.location.state
? this.props.location.state.userProfile
: {
firstName'',
familyName: '',
address: 'Enter your address',
city: 'Select your city',
country: 'Select your country',
field: '',
};
the message
field looks like an unchangeable data, so it is better not to put it into the react state, but use a ternary operator in the render
method
Upvotes: 1