React.js. Есть ли способ реализовать универсальный обработчик события "onChange" - PullRequest
0 голосов
/ 20 октября 2019

У меня некоторая путаница с 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 поле?

1 Ответ

2 голосов
/ 20 октября 2019

Этот простой обработчик изменений, о котором я могу подумать, используя prevState, таков:

handleChange = (event) => {   
  const name = event.target.name
  const value = event.target.value

  this.setState(prevState => ({
     workerInfo:{ 
       ...prevState.workerInfo,
       [name]: value
     }}
  ), ()=> console.log(this.state.workerInfo))
} 

Примечание: Я думаю, что нет необходимости использовать async/await при обновлении состояния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...