首页 > 解决方案 > 如何确保在 react js 中访问 props 之前对其进行更新

问题描述

下面给出的我的 React js 代码旨在在更改 cid 输入的值(触发 onBlur)时填充或更改输入的初始值,但只有在触发 onBlur 两次后才会填充或更改这些值。帮助我确定我在哪里犯了错误。代码如下:

import React, { Component } from 'react';
import { Form, Input, Button, Select } from 'antd';
import { connect } from 'react-redux';
import { addParticipant, updateParticipant, fetchParticpant } from './actions';

const { Option } = Select;
class CustomParticipantForm extends Component {
    state = {
        confirmDirty: false,
        participantID: null,
        requestType: 'post',
        form_data: {
            identity_no: null,
            name: null,
            email: null,
            gender: null,
        }
    };
    componentDidMount() {
        if (this.props.data !== null) {
            this.setState({
                ...this.state,
                form_data: {
                    ...this.state.form_data,
                    cid: this.props.data.cid,
                    name: this.props.data.name,
                    email: this.props.data.email,
                    gender: this.props.data.gender,
                }
            })
        }
    }

    handleSubmit = (event, postType, participantID) => {
        event.preventDefault();
        this.props.form.validateFieldsAndScroll(async (err, values) => {
            if (!err) {
                switch (postType) {
                    case 'post':
                        await this.props.addParticipant(values)
                        if (this.props.userError == null)
                            this.props.history.push('/create');
                        break;
                    case 'put':
                        await this.props.updateParticipant(values, participantID)
                        if (this.props.userError == null)
                            this.props.history.push(`/participant/${participantID}`);
                        break;
                    default:
                        console.log('default')
                }
            }
        });
    };

    handleConfirmBlur = e => {
        const { value } = e.target;
        this.setState({ confirmDirty: this.state.confirmDirty || !!value });
    };

    handleChange = () => {
        this.setState(
            {
                ...this.state,
                formChanged: true
            }
        )
    }
    getParticipantWithCID = (e) => {
        const { value } = e.target
        const { fetchParticpant } = this.props

        fetchParticpant(value) 

        if (this.props.stateParticipantData.length === 1) { //this line gets executed before the above line function call
            this.setState({
                ...this.state,
                form_data: {
                    ...this.state.form_data,
                    cid: this.props.stateParticipantData[0].cid,
                    name: this.props.stateParticipantData[0].name,
                    email: this.props.stateParticipantData[0].email,
                    gender: this.props.stateParticipantData[0].gender
                }
            })
        } else {
            this.setState({
                ...this.state,
                requestType: 'post',
                participantID: null,
                form_data: {
                    cid: value,
                    name: null,
                    email: null,
                    gender: null
                }
            })
        }
    }
    render() {
        const formItemLayout =
            this.props.formLayout === 'horizontal'
                ? {
                    labelCol: { span: 6 },
                    wrapperCol: { span: 14 },
                }
                : null;
        const { getFieldDecorator } = this.props.form;
        const prefixSelector = getFieldDecorator('prefix', {
            initialValue: '975',
        })(
            <Select style={{ width: 80 }}>
                <Option value="975">+975</Option>
            </Select>,
        );

        return (
            <Form
                layout={this.props.formLayout}
                autoComplete="off"
                onSubmit={event => this.handleSubmit(event,
                    this.state.requestType,
                    this.state.participantID
                )}
            >
                <Form.Item label="CID No." {...formItemLayout} extra="Please enter Alumni's CID ">
                    {getFieldDecorator('cid', {
                        initialValue: this.state.form_data.cid,
                        rules: [
                            {
                                required: true, message: "Alumni's CID is required!",
                                numeric: {
                                    message: "Please Provide valid CID No."
                                }
                            },
                        ],
                    })(
                        <Input type="text" onBlur={this.getParticipantWithCID} />,
                    )}
                </Form.Item>
                <Form.Item label="Name" {...formItemLayout} extra="Please enter user's full name">
                    {getFieldDecorator('name', {
                        initialValue: this.state.form_data.name,
                        rules: [
                            {
                                required: true,
                                message: "Participant's full name is required!"
                            },
                            {
                                type: 'string',
                                message: "Participant's full name must be string!"
                            },
                        ],
                    })(
                        <Input type="text" />,
                    )}
                </Form.Item>
                <Form.Item label="Gender" {...formItemLayout} extra="Please select Gender">
                    {getFieldDecorator('gender', {
                        initialValue: this.state.form_data.gender,
                        rules: [
                            {
                                required: true, message: "Gender is required!"
                            },
                        ],
                    })(
                        <Select placeholder="Select Gender" >
                            <Option value="Male">Male</Option>
                            <Option value="Female">Female</Option>
                        </Select>,
                    )}
                </Form.Item>
                <Form.Item label="Email" {...formItemLayout} extra="Please enter user's email address">
                    {getFieldDecorator('email', {
                        initialValue: this.state.form_data.email,
                        rules: [
                            {
                                required: true, message: "Email address is required!"
                            },
                            {
                                type: 'email', message: 'The input is not a valid email address!'
                            },
                        ],
                    })(
                        <Input type="email" />,
                    )}
                </Form.Item>
                <Form.Item>
                    <Button
                        type="primary"
                        htmlType="submit"
                    >
                        {this.props.btnText}
                    </Button>
                </Form.Item>
            </Form >
        );
    }
}

const ParticipantForm = Form.create()(CustomParticipantForm);

const mapStateToProps = state => {
    return {
        stateParticipantData: state.participant
    }
}

const mapDispatchToProps = dispatch => {
    return {
        addParticipant: (data) => dispatch(addParticipant(data)),
        updateParticipant: (data, participantID) => dispatch(updateParticipant(data, participantID)),
        fetchParticpant: (cid) => dispatch(fetchParticpant(cid))
    }
}


export default connect(mapStateToProps, mapDispatchToProps)(ParticipantForm);

标签: reactjsreact-reduxantd

解决方案


推荐阅读