У меня некоторая путаница с setState React. Я пытался реализовать метод changeHandler
для изменения состояния, но я столкнулся с некоторыми проблемами.
Я создал 4 текстовых поля, свойство name
указывает на свойство this.state.workerInfo.foo
, поэтому внутри changeHandler
iизвлеките event.target.name
, чтобы связать новое значение с состоянием.
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>
}
}
Я реализовал 2 метода handleChange
, но они не кажутся хорошими.
Первый метод работает, но я думаю, что делать копию состояния не очень хорошая идея. .
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);
}
Второй метод вообще не работает.
Он уничтожает все поля внутри workerInfo
и помещает только одно, которое было изменено.
handleChange = () => async event => {
const name = event.target.name
await this.setState({workerInfo:{ [name]: event.target.value}})
});
};
Использование предыдущего состояния также дает неверный результат.
this.setState((prevState) => {
return {workerInfo: { ...prevState.workerInfo, [name]: event.target.value}}
});
Так как же реализовать универсальную функцию changeHandler
, которая будет обновлять состояние, используя name
текстового поля для связи сstate.workerInfo
поле?