React.js。有没有办法实现通用的“ onChange”事件处理程序

时间:2019-10-20 09:00:10

标签: reactjs material-ui state

我对React的setState感到有些困惑。 我尝试实现changeHandler方法来更改状态,但是我遇到了一些问题。

我创建了4个文本字段,name属性表示this.state.workerInfo.foo的属性,因此我在changeHandler内提取了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}}
        });

那么使用文本字段的changeHandlername字段链接来实现通用state.workerInfo功能的方法是什么,该方法将更新状态?

1 个答案:

答案 0 :(得分:2)

我可以想到的使用这个简单的变更处理程序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