简体   繁体   English

React antd 4 Form in Modal resetFields 显示错误数据

[英]React antd 4 Form in Modal resetFields showing wrong data

I am having trouble understanding why I am seeing this unexpected behavior.我无法理解为什么我会看到这种意外行为。 If I have some data that I am passing into a prop on an object that has a modal with a form done as shown below and I click on a button, then cancel, then click on a different button, the form is showing the previously clicked state each time.如果我有一些数据要传递到 object 上的道具中,该道具具有如下所示的表单,然后单击一个按钮,然后取消,然后单击另一个按钮,该表单显示先前单击的state 每次。 Within the useEffect code, I can see that the correct person is loaded, though the form initializes the previous person.在 useEffect 代码中,我可以看到加载了正确的人,尽管表单初始化了前一个人。

import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Button, Modal, Form, Input } from "antd";

const PersonEditForm = ({ person, onCreate, onCancel }) => {
  const [form] = Form.useForm();
  const prevRef = useRef();

  useEffect(() => {
    if (prevRef.current === null && person) {
      form.resetFields();
    }
    prevRef.current = person;
  });

  return (
    person && (
      <Modal
        visible={!!person}
        title="Person Editor"
        okText="Create"
        cancelText="Cancel"
        onCancel={onCancel}
        onOk={() => {
          form
            .validateFields()
            .then(values => {
              onCreate(values);
            })
            .catch(info => {
              console.log("Validate Failed:", info);
            });
        }}
      >
        <Form
          form={form}
          layout="vertical"
          name="form_in_modal"
          initialValues={person}
        >
          <Form.Item
            name="name"
            label="Name"
            rules={[
              {
                required: true,
                message: "Please input the person's name!"
              }
            ]}
          >
            <Input />
          </Form.Item>
        </Form>
      </Modal>
    )
  );
};

const CollectionsPage = () => {
  const [person, setPerson] = useState(null);

  const onCreate = values => {
    console.log("Received values of form: ", values);
    setPerson(null);
  };

  return (
    <div>
      <Button
        type="primary"
        onClick={() => {
          setPerson({ name: "Bob" });
        }}
      >
        Edit Bob
      </Button>
      <Button
        type="primary"
        onClick={() => {
          setPerson({ name: "John" });
        }}
      >
        Edit John
      </Button>
      <Button
        type="primary"
        onClick={() => {
          setPerson({ name: "Phil" });
        }}
      >
        Edit Phil
      </Button>
      <PersonEditForm
        person={person}
        onCreate={onCreate}
        onCancel={() => {
          setPerson(null);
        }}
      />
    </div>
  );
};

ReactDOM.render(<CollectionsPage />, document.getElementById("container"));

However, if I remove the person && ( from my <PersonEditForm> component, it works as expected. Can anyone explain the subtle difference I'm running into here? I have down-stream complex form components that weren't handling a null state, so I wanted to only create the modal if a person was being edited.但是,如果我从我的<PersonEditForm>组件中删除person && ( ,它会按预期工作。谁能解释我在这里遇到的细微差别?我有下游复杂的表单组件不处理 null state ,所以我只想在一个人被编辑时创建模态。

The code doesn't work because of some funny race condition arising from misusing form.resetForm to change initialValues .由于滥用form.resetForm来更改initialValues引起的一些有趣的竞争条件,该代码不起作用。 You would probably have to go into the actual implementation of initialValues to figure out what is going wrong.您可能必须将 go 放入initialValues的实际实现中才能找出问题所在。

However, if instead of reseting the form inside of useEffect , you were to assign the clicked person value using form.setFieldsValue(person) , your code would work as intended.但是,如果不是在useEffect中重置表单,而是使用form.setFieldsValue(person)分配单击的person值,您的代码将按预期工作。

https://codesandbox.io/s/hungry-christian-cdn7t?file=/src/index.js https://codesandbox.io/s/hungry-christian-cdn7t?file=/src/index.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM