reactjs - 如何确保在 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);
解决方案
推荐阅读
- reactjs - 在 Mikrotik 路由器板上本地部署 NextJS
- javascript - 如何像在 Java 中一样在 JS 中的构造函数之外设置属性?
- javascript - 如何在我的班级名称上使用 querySelectorAll
- java - Using Lombok @Data annotation above class with field names like "iPhone" causing problems
- javascript - Vue 应用程序中的嵌套 v-for 使用之前的状态
- amazon-web-services - AWS S3 复制性能
- python - 在 GCP 实例上运行多个作业时,PyTorch 数据加载“冻结”
- sql - 从左 jon 中排除 Null
- ios - 将离屏 SwiftUI 视图居中
- java - 我想在不使用 sort() 函数的情况下按升序对数组元素进行排序