I've got some confusion with React's setState.
I tried to implement changeHandler
method to change the state, but i face some problems.
I have created 4 textfields, name
property indicates a property of this.state.workerInfo.foo
, so inside the changeHandler
i extract the event.target.name
to link new value with the state.
class EditableWorkerProfile extends Component {
constructor(props) {
super(props);
this.state = {
pending: false,
shouldAdd: false,
worker_id: props.worker._id,
workerInfo: {
login: props.worker.login,
balance: props.worker.balance,
phoneNum: props.worker.phoneNum.replace(new RegExp("(^\\+7)|(^8)"), "7"),
birthDate: props.worker.birthDate,
address: props.worker.address,
city: props.worker.city,
name: props.worker.name,
isDriver: props.worker.isDriver,
veh_is_open: this.props.worker.isDriver ? this.props.worker.veh_is_open : false,
veh_height: this.props.worker.isDriver ? this.props.worker.veh_height : "0",
veh_width: this.props.worker.isDriver ? this.props.worker.veh_width : "0",
veh_length: this.props.worker.isDriver ? this.props.worker.veh_length : "0",
veh_loadingCap: this.props.worker.isDriver ? this.props.worker.veh_loadingCap : "0",
veh_frameType: this.props.worker.isDriver ? this.props.worker.veh_frameType : "Открытый борт" ,
height: !this.props.worker.isDriver ? this.props.worker.height : "0",
weight: !this.props.worker.isDriver ? this.props.worker.weight : "0",
rating: props.worker.rating,
}
}
}
render() {
let { classes, worker } = this.props;
let { pending, shouldAdd, workerInfo, worker_id } = this.state;
return <Card>
<CardBody>
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<TextField label="Balance" name="balance" onChange={this.handleChange} />
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField label="Login" name="login" onChange={this.handleChange} />
</GridItem>
<GridItem id='worker_phone' xs={6} sm={6} md={6}>
<TextField label="Phone number" name="phoneNum" onChange={this.handleChange} />
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField label="Address" name="address" onChange={this.handleChange} />
</GridItem>
</GridContainer>
</GridContainer>
</CardBody>
</Card>
}
}
I have realised 2 methods handleChange
but they dont seems good.
The first method works, but i think it is not a good idea to make a copy of the state.
handleChange = (is_check = false) => (e) => {
let value = e.target[is_check ? "checked" : "value"]
this.updateState(e.target.name, value);
}
updateState = async (field, value) => {
//Slow method
field = 'workerInfo.'+field
let init_state = _.clone(this.state, true);
_.set(init_state, field, value);
await this.setState(init_state);
}
The second method are not working at all.
It destroys all fields inside the workerInfo
and put only one, which was changed.
handleChange = () => async event => {
const name = event.target.name
await this.setState({workerInfo:{ [name]: event.target.value}})
});
};
Using of previous state give incorrect result too.
this.setState((prevState) => {
return {workerInfo: { ...prevState.workerInfo, [name]: event.target.value}}
});
So what is the way to implement universal changeHandler
function, which will be update the state, using name
of the textfield to link with state.workerInfo
field?