由于承诺而在状态更改之前发生更新?

时间:2019-06-06 17:43:53

标签: javascript reactjs

我具有此更新功能,该功能应该在单击“更新”按钮时更新组件的状态和视图;但是,它仅在单击“更新”按钮后才开始更新。就像,我必须单击“更新”,然后更改表单输入以查看视图的更改。

Expectation: 

 Step 1: Change Form input then click 'Update' button
 Step 2: State and View changes

Reality/Issue:

 Step 1: In order to see the change, I have to click the 'Update' button first
 Step 2: Then I can change Form input and see the change in my view.

如何使状态和组件视图仅在单击“更新”按钮后才更改?

我发现Promises是异步的,因此我尝试添加回调,使用异步等待或移动代码顺序,但是仍然会产生相同的问题。

export class EducationPage extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        incomingClass: {...this.props.location.state.data},
        alert: {
            display: false
        }};
    this.updateEdu = this.updateEdu.bind(this);
    this.handleChange = this.handleChange.bind(this);
}   

handleChange = (event) => {
    const target = event.target;
    const value =  target.value;
    const name = target.name;
    this.setState((prevState) => {
        let newState = {};
        let data = Object.assign({}, prevState.data);
        data[name] = value;
        newState.data = data;
        return newState;
    });
};

updateEdu = (e) => {
    e.preventDefault();
    let newEdu = {...this.state.incomingClass};
    BackEndRestPromiseService.updateEdu(newEdu).then(data => { // Promise
        this.setState({
            incomingClass: data
        }, () => console.log(data));
    }).catch(e => {
    console.log(e);
        this.setState({
            error: "Error!"
        });
    });
}

render() {
return (
    <div>
        <Form onSubmit={e => this.updateEdu(e)}>
        <Button type="submit">Update</Button>
            <Form.Row>
                <Form.Group as={Col}>
                    <Form.Label>School</Form.Label>
                    <Form.Control id="school" name="school" placeholder="School" value={this.state.incomingClass.school || ""} onChange={this.handleChange}/>
                </Form.Group>

                <Form.Group as={Col}>
                    <Form.Label>Grade</Form.Label>
                    <Form.Control id="grade" name="grade" placeholder="Grade #" value={this.state.incomingClass.grade || ""} onChange={this.handleChange}/>
                </Form.Group>
            </Form.Row>
        </Form>
    </div>
)
}

1 个答案:

答案 0 :(得分:2)

我将简化您的某些代码以使其更易于调试。

handleChange = (event) => {
    const { name, value } = event.target;
    this.setState(prevState => 
      ({ incomingClass: { ...prevState.incomingClass, [name]: value } }));
};

我在这里注意到的是,您在初始状态下没有data属性,只有incomingClass。但是您的handleChange方法在prevState.data上运行。 setState还支持部分更新状态。因此,您不必获取完整的先前状态即可进行设置。

此外,无需重建incomingClass,然后再将其发送到服务器。

updateEdu = (e) => {
    e.preventDefault();
    BackEndRestPromiseService.updateEdu(this.state.incomingClass)
     .then(data => this.setState({ incomingClass: data }))
     .then(() => console.log(data))
     .catch(e => { console.log(e); this.setState({ error: "Error!" }) });
}

由于您已经使用了类属性,因此无需在此处使用lambda或对其进行绑定。

<Form onSubmit={this.updateEdu}>

这是不必要的,因为您正在使用类属性

this.updateEdu = this.updateEdu.bind(this);
this.handleChange = this.handleChange.bind(this);