首页 > 解决方案 > React-Final-Form中初始表单组件重新渲染后如何保留Dirty状态和数据

问题描述

由于react-final-form社区的长期响应,我将我的问题重定向到这里,以至少了解最终形式的行为,以便按照我的意图使用它。

当前的行为是什么?

我正在使用 nextjs 来支持多分页,并且我绞尽脑汁了解如何在页面中保留脏内容。案例场景是用户编辑表单,然后他们通过移动到另一个页面来释放表单。在确认他们需要的一些信息后,用户返回表单继续编辑它。我的问题是,即使我使用keepDirtyOnReinitializeprop,它也会保存脏的值,但它实际上并没有识别从第一次初始化时它是脏的形式,也没有在返回它时识别出它是脏的。即使在我重新加载页面之后,hard reload它也会将所有内容恢复到初始状态,用户会丢失所有内容:(此外,我正在使用类似Redux Exampleand的示例Loading, Normalizing, Saving, and Reinitializing来保留表单的状态并在需要时将其恢复。

预期的行为是什么?

在用户从不同页面返回表单后保留脏

沙盒代码

const FormControl = (
  {
    formName,
  },
) => {
  return (
    <LoadForm
      formName={formName}
      initialValues={{ newField: "test" }}
      onSubmit={(data) => {}}
    >
      {({ form, handleSubmit, submitting, pristine, ...rest }) => (
        <form onSubmit={handleSubmit}>
          <FormControlRedux formName={formName}/>
          <div>
            <button type="submit" disabled={submitting || pristine}>save</button>
            <button onClick={form.reset} type="button">reset</button>
          </div>

          <Field name="newField" component="input"/>
        </form>
      )}
    </LoadForm>
  );
};

const FormControlRedux = ({ formName }) => {
  const { setData } = useFormRedux(formName);
  return <FormSpy onChange={state => setData(state)}/>;
};

const LoadForm = (
  {
    onSubmit,
    formName,
    initialValues,
    ...rest
  }
) => {
  // example 1: https://codesandbox.io/s/xr0mvl1904?file=/LoadSaveReinitializeForm.js:661-675
  // example 2: https://codesandbox.io/s/4xq2qpzw79?file=/src/index.js:1312-1325
  const initialState = {
    isLoading: false,
    original: undefined,
    current: undefined,
  }
  const { data: subscription } = useFormRedux(formName);
  const reducer = (state, action) => ({ ...state, ...action })
  const [state, setState] = React.useReducer(reducer, initialState);

  const loadForm = () => {
    setState({ isLoading: true });
    const original = initialValues || {};
    const current = subscription.dirty ? subscription.values : original;
    setState({ isLoading: false, current, original });
  }

  React.useEffect(() => { loadForm();  }, [])

  return state.isLoading || !state.current
    ? <div>loading...</div>
    : <Form {...rest} {...{ subscription }} onSubmit={onSubmit}
      keepDirtyOnReinitialize={subscription.dirty}
      initialValues={state.current}
    />
}

export default FormControl;

原始问题发布在这里

标签: reactjsreact-final-form

解决方案


推荐阅读