Skip to content
This repository has been archived by the owner on Jan 10, 2025. It is now read-only.

Can we have fine grain control over a Forms fields dirty state #323

Closed
1 of 2 tasks
laranoell opened this issue Oct 2, 2018 · 5 comments · Fixed by #446
Closed
1 of 2 tasks

Can we have fine grain control over a Forms fields dirty state #323

laranoell opened this issue Oct 2, 2018 · 5 comments · Fixed by #446
Assignees

Comments

@laranoell
Copy link

laranoell commented Oct 2, 2018

Overview

We have a scenario in which a form field needs to fetch some data (it's a product picker with selected values) and then update formData with the fetched values.

In this case, we don't want to wait for all of the initial values to resolve, so that we can allow merchants to interact with the form straight away.

We also do not want the dirty state to be true, when the formData is updated to reflect the fetched values.

Can we add a feature that allows fine grain control of a fields dirty state?

Type

  • New feature

  • I have described this issue in a way that is actionable (if possible)

@laranoell laranoell self-assigned this Oct 2, 2018
@marutypes
Copy link
Contributor

Maybe we could do something for updating the initialValue of a single field (like adding updateInitialValue to the fieldDescriptors or something

@marutypes
Copy link
Contributor

Could you put together an example of a usecase for this by forking the sandbox?

@marutypes
Copy link
Contributor

marutypes commented Dec 13, 2018

So I think there are two things here:

  • we can get away with only resetting fields that actually got new initialValues by default, avoiding resetting the whole form if only one field ends up changed asynchronously
  • we can expose an api to plug in custom logic for how to update fields when their initial values change

@laranoell how do you feel about the following api for the latter?

interface Props<Fields> {
  initialValues: Fields;
  validators?: Partial<ValidatorDictionary<Fields>>;
  onSubmit?: SubmitHandler<Fields>;
  validateOnSubmit?: boolean;
  // new optional prop that gets called for each field when initialValues changes
  onInitialValueUpdate?: InitialValueMapper<Fields>;
  children(form: FormDetails<Fields>): React.ReactNode;
}

// looks like this (I know the generics are wordy)
interface InitialValueMapper<Fields> {
  <Key extends keyof Fields>(
    value: Fields[Key]
    oldState: FieldStates<Fields>[Key],
    key: Key,
  ): FieldState<Fields>;
}

// example usage doing custom stuff based on the key

<FormState
  initialValues={this.initialValues}
  onInitialValueUpdate={(
    value
    oldState,
    key,
  ) => (
    if (key === 'myListField') {
      return updateAndAddToList(value, oldState);
    }
    
    if (key === 'someFieldThatNeedsToReset') {
      return FormState.resetField(value, oldState, key);
    }

    // otherwise reconcile
    return FormState.reconcileField(value, oldState, key);
  }}
>

The other API I was considering for this was noReset, which would just make it so the initialValues are merged in but the form state is never reset. This would mean forms using it would need to use a key to force a reset when they need it.

<FormState
  initialValues={this.initialValues}
  noReset
  // key will force the whole formstate to remount (thus resetting it)
  // use anything that is garaunteed to update when the form is submitted successfully
  // could also be a `revisionNumber` if we had those, or something manual in state
  key={this.data.updatedAt}

@rexmac
Copy link
Contributor

rexmac commented Dec 19, 2018

we can get away with only resetting fields that actually got new initialValues by default, avoiding resetting the whole form if only one field ends up changed asynchronously

👍

@laranoell
Copy link
Author

laranoell commented Dec 20, 2018

@TheMallen hey, yea, I think that this onInitialValuesChange="reset-where-changed" works to solve the problem as described. I'll reach out the code owners to share this 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants