Reactjs 反应antd步骤重新呈现子组件以适应父状态更改

Reactjs 反应antd步骤重新呈现子组件以适应父状态更改,reactjs,antd,Reactjs,Antd,我有一份很长的登记表,我使用AntD的steps组件将其分为几个部分 //定义的子窗体组件 steps = { basicInfo: { title: 'Basic Info', content: ( <BasicInfoForm form={this.props.form} user={this.user} /> ), }, addresses: { title: 'Addresses', content: (

我有一份很长的登记表,我使用AntD的steps组件将其分为几个部分

//定义的子窗体组件

steps = {
 basicInfo: {
  title: 'Basic Info',
  content: (
    <BasicInfoForm
      form={this.props.form}
      user={this.user}
    />
  ),
 },
 addresses: {
  title: 'Addresses',
  content: (
    <Address
      form={this.props.form}
      addresses={this.user.addresses}
    />
  ),
 },
 contactInfo: {
  title: 'Contact Info',
  content: (
    <PhoneForm
      form={this.props.form}
      contactInfo={this.user.contactInfo}
    />
  ),
 }, 
}
//子组件

interface IAddressFormProps {
 form: WrappedFormUtils;
 addresses: IAddress[];
 fieldName: string;
}
class Address extends Component<IAddressFormProps> {
 totalAddresses: any = this.props.addresses && this.props.addresses ? 
 this.props.addresses : ([{}] as IAddress[]);

 state = {
  totalAddresses: this.totalAddresses ? this.totalAddresses : ([] as IAddress[]),
};

 addAddress = () => {
  this.setState((prevState: any) => ({
  totalAddresses: [...prevState.totalAddresses, { lineOne: '', lineTwo: '', lineThree: '', city: '', state: '', zip: '', type: '' }],
}));
 };

 removeAddress = (index: number) => {
  this.setState({
  totalAddresses: this.state.totalAddresses.filter((item: IAddress, addressIndex: number) => index !== addressIndex),
 });
 };

 render() {
  const { getFieldDecorator } = this.props.form;
  const fieldName = this.props.fieldName;
  return (
  <Fragment>
    {this.state.totalAddresses.map((item: IAddress, index: number) => {
      return (
        <Row key={'container-' + index} type="flex" justify="start" gutter={16}>
          <Col span={6}>
            <Form.Item label="Type" key={'type-' + index}>
              {getFieldDecorator(`${fieldName}[${index}].type`, {
                initialValue: item.type,
                rules: [{ required: true, message: 'Please input address type!' }],
              })(
                <Select placeholder="Type">
                  <Option value="Mailing">Mailing</Option>
                  <Option value="Business">Business</Option>
                  <Option value="Home">Home</Option>
                  <Option value="Other">Other</Option>
                </Select>
              )}
            </Form.Item>
            <Form.Item label="Line One" key={'lineOne-' + index}>
              {getFieldDecorator(`${fieldName}[${index}].lineOne`, {
                initialValue: item.lineOne,
                rules: [{ required: true, message: 'Please input line one!' }],
              })(<Input placeholder="Line One" />)}
            </Form.Item>
            <Form.Item label="Line Two" key={'lineTwo-' + index}>
              {getFieldDecorator(`${fieldName}[${index}].lineTwo`, {
                initialValue: item.lineTwo,
                rules: [{ required: false, message: 'Please input line two!' }],
              })(<Input placeholder="Line Two" />)}
            </Form.Item>
            <Form.Item label="Line Three" key={'lineThree-' + index}>
              {getFieldDecorator(`${fieldName}[${index}].lineThree`, {
                initialValue: item.lineThree,
                rules: [{ required: false, message: 'Please input line three!' }],
              })(<Input placeholder="Line Three" />)}
            </Form.Item>
          </Col>
          <Col span={9}>
            <Form.Item label="City" key={'city-' + index}>
              {getFieldDecorator(`${fieldName}[${index}].city`, {
                initialValue: item.city,
                rules: [{ required: true, message: 'Please input city!' }],
              })(<Input placeholder="City" />)}
            </Form.Item>
            <Form.Item label="State" key={'state-' + index}>
              {getFieldDecorator(`${fieldName}[${index}].state`, {
                initialValue: item.state,
                rules: [{ required: true, message: 'Please input state!' }],
              })(<Input placeholder="State" />)}
            </Form.Item>
            <Form.Item label="Zip" key={'zip-' + index}>
              {getFieldDecorator(`${fieldName}[${index}].zip`, {
                initialValue: item.zip,
                rules: [{ required: true, message: 'Please input zip!' }],
              })(<Input placeholder="Zip" />)}
            </Form.Item>
          </Col>
          <Col span={4}>
            <Button onClick={() => this.removeAddress(index)}>Remove</Button>
          </Col>
        </Row>
      );
    })}
    <Button onClick={() => this.addAddress()}>Add address</Button>
  </Fragment>
 );
 }
}
formprops接口{
形式:包装成册;
地址:IAddress[];;
字段名:字符串;
}
类地址扩展组件{
totalAddresses:any=this.props.addresses&&this.props.addresses?
this.props.addresses:([{}]作为IAddress[]);
状态={
totalAddresses:this.totalAddresses?this.totalAddresses:([]作为IAddress[]),
};
地址=()=>{
this.setState((prevState:any)=>({
totalAddresses:[…prevState.totalAddresses,{lineOne:'',LineII:'',lineThree:'',城市:'',州:'',邮编:'',类型:''}],
}));
};
removeAddress=(索引:number)=>{
这是我的国家({
totalAddresses:this.state.totalAddresses.filter((项:iadAddress,addressIndex:number)=>index!==addressIndex),
});
};
render(){
const{getFieldDecorator}=this.props.form;
const fieldName=this.props.fieldName;
返回(
{this.state.totalAddresses.map((项:IAddress,索引:number)=>{
返回(
{getFieldDecorator(`${fieldName}[${index}]。类型`{
initialValue:item.type,
规则:[{required:true,消息:“请输入地址类型!”}],
})(
邮寄
生意
家
其他
)}
{getFieldDecorator(`${fieldName}[${index}].lineOne`{
初始值:item.lineOne,
规则:[{required:true,消息:“请输入第一行!”},
})()}
{getFieldDecorator(`${fieldName}[${index}]。第二行`{
初始值:item.lineTwo,
规则:[{required:false,消息:“请输入第二行!”},
})()}
{getFieldDecorator(`${fieldName}[${index}]。第三行`{
initialValue:item.lineThree,
规则:[{required:false,消息:“请输入第三行!”},
})()}
{getFieldDecorator(`${fieldName}[${index}]。城市`{
初始值:item.city,
规则:[{必需:true,消息:'请输入城市!'],
})()}
{getFieldDecorator(`${fieldName}[${index}]。状态`{
初始值:item.state,
规则:[{required:true,消息:“请输入状态!”},
})()}
{getFieldDecorator(`${fieldName}[${index}].zip`{
initialValue:item.zip,
规则:[{required:true,消息:'请输入zip!'],
})()}
this.removeAddress(index)}>Remove
);
})}
this.addAddress()}>添加地址
);
}
}
我希望在整个步骤中保持用户对象的状态,即来回移动。 在表单提交时,更新用户对象

next = (addEditUser: MutationFn<any, any>) => {
 const form = this.props.form;
 form.validateFields(async (err: any, values: any) => {
  if (err) {
    return false;
  }
  values.id = this.userId;
  let variables = this.parentId ? { user: values, parentId: this.parentId } : { user: values };
  const result = await addEditUser({ variables: variables });
  if (result && result.data) {
    if (this.state.currentStep === this.state.steps.length - 1) {
      this.props.history.push('/user');
    } else {
      this.user = Object.assign(this.user, values);
      const currentStep = this.state.currentStep + 1;
      this.setState({ currentStep });
    }
  }
 });
};
next=(addEditUser:MutationFn)=>{
const form=this.props.form;
form.validateFields(异步(err:any,values:any)=>{
如果(错误){
返回false;
}
values.id=this.userId;
让变量=this.parentId?{user:values,parentId:this.parentId}:{user:values};
const result=await addEditUser({variables:variables});
if(结果和结果数据){
if(this.state.currentStep==this.state.steps.length-1){
this.props.history.push('/user');
}否则{
this.user=Object.assign(this.user,value);
const currentStep=this.state.currentStep+1;
这个.setState({currentStep});
}
}
});
};
用户对象已正确更新,但子组件未正确更新。为什么?


提前感谢。

要将
道具
传递到
状态
,您必须使用
getDerivedStateFromProps
方法

在您的子类中,您可以添加以下内容-这是您的
地址
组件的一个示例,您可以通过
道具
从父组件接收
地址

static getDerivedStateFromProps(props, state) {
   const { address } = props;
   if(address !== state.address) return { address }
}
现在,如果父组件发送新的
道具
,函数将检查
道具地址
是否不同于
状态。地址
-这是子组件状态-如果不同,则将其设置为从
道具
接收的值

static getDerivedStateFromProps(props, state) {
   const { address } = props;
   if(address !== state.address) return { address }
}

将此方法添加到您的
Address
类中,它应该可以工作

以便将
props
传递到
状态
您必须使用
getDerivedStateFromProps
方法

在您的子类中,您可以添加以下内容-这是您的
地址
组件的一个示例,您可以通过
道具
从父组件接收
地址

static getDerivedStateFromProps(props, state) {
   const { address } = props;
   if(address !== state.address) return { address }
}
现在,如果父组件发送新的
道具
,函数将检查
道具地址
是否不同于
状态。地址
-这是子组件状态-如果不同,则将其设置为从
道具
接收的值

static getDerivedStateFromProps(props, state) {
   const { address } = props;
   if(address !== state.address) return { address }
}

将此方法添加到您的
地址
类中,它应该可以工作

请提供完整的代码(React),以便更好地理解您的app@Sabbin我已经添加了代码。如果需要,请告诉我。好的,这里的问题是子组件的
状态没有更改?@Sabbin如何?我正在通过道具将更新后的值传递到状态。请提供完整的代码(React),以便更好地理解您的app@Sabbin我已经添加了代码。如果需要,请告诉我。好的,