react-final-form icon indicating copy to clipboard operation
react-final-form copied to clipboard

How to retain dirty after the Rerender of the initial form component

Open gyto23 opened this issue 4 years ago • 1 comments

What is the current behavior?

I am using nextjs to support multi paging and I strangle to understand how to retain a dirty within pages. The case scenario is where user is edited the form and then they release form by moving to another page. After confirming some of the information they need, user coming back to the form to continue editing it. My issue is that even if I use keepDirtyOnReinitialize prop, it saves the value of the dirty, but it doesn't actually identify the form it was dirty from first initialization nor is dirty when coming back to it. Even after I have reloaded the page by hard reload it will bring everything to initial state, where user looses everything :( In addition, I am using examples like Redux Example and Loading, Normalizing, Saving, and Reinitializing to retain the state of the form and bring it back when I needed.

What is the expected behavior?

To retain dirty after user came back to the form from different page

Sandbox Code

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;

What's your environment?

"final-form": "4.20.2", "react-final-form": "6.5.2"

gyto23 avatar Mar 10 '21 18:03 gyto23

Any updates on this?

smaidah avatar Jun 10 '22 08:06 smaidah