Skip to content

Commit

Permalink
fix(core/presentation): clear out prior 'touched' values in useSaveRe…
Browse files Browse the repository at this point in the history
…storeMutuallyExclusiveField (#8290)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
christopherthielen and mergify[bot] committed May 18, 2020
1 parent 7bf423d commit 495cf7f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ describe('useSaveRestoreMutuallyExclusiveFields hook', () => {
expect(formikRef.current.getFormikBag().values).toEqual({ pizzaOrSandwich: 'sandwich' });
});

it(`clears out 'touched' status for 'pizza' fields when the user chooses 'sandwich'`, () => {
const formikRef = React.createRef<Formik>();
const wrapper = setupTest(formikRef);
formikRef.current.setFieldTouched('topping', true);
formikRef.current.setFieldTouched('crust', true);

expect(formikRef.current.getFormikBag().touched.topping).toBe(true);
expect(formikRef.current.getFormikBag().touched.crust).toBe(true);

formikRef.current.setFieldValue('pizzaOrSandwich', 'sandwich');
wrapper.setProps({});

expect(formikRef.current.getFormikBag().touched.topping).toBe(null);
expect(formikRef.current.getFormikBag().touched.crust).toBe(null);
});

it(`restores previously saved 'pizza' fields when toggling back to 'pizza'`, () => {
const formikRef = React.createRef<Formik>();
const wrapper = setupTest(formikRef);
Expand All @@ -98,6 +114,24 @@ describe('useSaveRestoreMutuallyExclusiveFields hook', () => {
});
});

it(`restores previously saved touched statuses for 'pizza' fields when toggling back to 'pizza'`, () => {
const formikRef = React.createRef<Formik>();
const wrapper = setupTest(formikRef);
formikRef.current.setFieldTouched('topping', true);
formikRef.current.setFieldTouched('crust', true);

expect(formikRef.current.getFormikBag().touched.topping).toBe(true);
expect(formikRef.current.getFormikBag().touched.crust).toBe(true);

formikRef.current.setFieldValue('pizzaOrSandwich', 'sandwich');
wrapper.setProps({});
formikRef.current.setFieldValue('pizzaOrSandwich', 'pizza');
wrapper.setProps({});

expect(formikRef.current.getFormikBag().touched.topping).toBe(true);
expect(formikRef.current.getFormikBag().touched.crust).toBe(true);
});

it(`restores previously saved 'pizza' and 'sandwich' fields when toggling back and forth`, () => {
const formikRef = React.createRef<Formik>();
const wrapper = setupTest(formikRef);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,43 @@ export function useSaveRestoreMutuallyExclusiveFields(
}

const previousFieldSetKey = usePrevious(currentFieldSetKey);
const [savedData, setSavedData] = useState<SavedFieldsets>({});
const [savedValues, setSavedValues] = useState<SavedFieldsets>({});
const [savedTouched, setSavedTouched] = useState<SavedFieldsets>({});

// Whenever the fieldset key changes, save and clear out the
// previous fieldset's values and restore the current fieldset's values.
useEffect(() => {
// Only run the effect if the the value is changing. Do not run on first render.
if (!!previousFieldSetKey && currentFieldSetKey !== previousFieldSetKey) {
const fieldsToSave = mutuallyExclusiveFieldSets[previousFieldSetKey] ?? [];
const fieldsToRestore = mutuallyExclusiveFieldSets[currentFieldSetKey] ?? [];

const dataToSave = fieldsToSave.reduce((data, path) => {
const valuesToSave = fieldsToSave.reduce((data, path) => {
data[path] = get(formik.values, path);
return data;
}, {} as FieldsetData);
setSavedData({ ...savedData, [previousFieldSetKey]: dataToSave });
setSavedValues({ ...savedValues, [previousFieldSetKey]: valuesToSave });

const dataToRestore = savedData[currentFieldSetKey] || {};
const touchedToSave = fieldsToSave.reduce((data, path) => {
data[path] = get(formik.touched, path);
return data;
}, {} as FieldsetData);
setSavedTouched({ ...savedTouched, [previousFieldSetKey]: touchedToSave });

fieldsToSave.forEach(field => formik.setFieldValue(field, undefined));
fieldsToRestore.forEach(path => {
if (dataToRestore.hasOwnProperty(path)) {
formik.setFieldValue(path, savedData[currentFieldSetKey][path]);
fieldsToSave.forEach(field => {
formik.setFieldValue(field, undefined);
formik.setFieldTouched(field, null);
});

// Restore the saved touched/values
const valuesToRestore = savedValues[currentFieldSetKey] || {};
const touchedToRestore = savedTouched[currentFieldSetKey] || {};
fieldsToRestore.forEach(field => {
if (valuesToRestore.hasOwnProperty(field)) {
formik.setFieldValue(field, savedValues[currentFieldSetKey][field]);
}
if (touchedToRestore.hasOwnProperty(field)) {
formik.setFieldTouched(field, savedTouched[currentFieldSetKey][field]);
}
});
}
Expand Down

0 comments on commit 495cf7f

Please sign in to comment.