final-form / react-final-form

🏁 High performance subscription-based form state management for React
https://final-form.org/react
MIT License
7.39k stars 481 forks source link

parse and format is not working for initialValues #431

Open alirezavalizade opened 5 years ago

alirezavalizade commented 5 years ago

checkout this sandbox

Edit 🏁 React Final Form - Parse and Format

mcmxcdev commented 4 years ago

@erikras is there any reasoning why it is not the default for parse() and format() to be applied for initialValues, but rather on onChange?

It seems like 10+ people need this and I just came across this issue at work with no way to work around it.

I could eventually take a look and provide a PR, if desired.

pulse00 commented 4 years ago

@erikras any feedback on this issue would be highly appreciated. If this is not intentional, we're happy to provide a PR, but we're currently unsure if this should be supported or not.

alirezavalizade commented 4 years ago

for me it's not an issue anymore, because I used custom component then I fixed the issue there, just saw this one and wanted to report :)

mrassili commented 4 years ago

@erikras this is still an issue, can you explain the reasoning for not running the initial value by format() ?

erikras commented 4 years ago

I'm not sure I understand the problem here.

Value Flow

flow

Updated Sandbox

Is this not the desired functionality?

Edit 🏁 React Final Form - Parse and Format

mrassili commented 4 years ago

@erikras thanks for the drawing. the problem is when I want to change the value manually (like when filling a single field by clicking a button) I do onChange(value) but the value is not parsed per the parse function I gave to the field. same for initialValue it doesn't go through format

erikras commented 4 years ago

@mrassili Can you provide a sandbox?

reinrl commented 4 years ago

@alirezavalizade I took your original sandbox from above (now forked as https://codesandbox.io/s/react-final-form-parse-and-format-forked-tg5zt), and made one big change at line 56 (also had to change the default value to be a string instead of a number):

<Field
  name="phone"
  component="input"
  type="text"
  // you did not have a format prop here originally??
  format={normalizePhone}
  //////////
  parse={normalizePhone}
  placeholder="(999) 999-9999"
/>

After doing that, visually things seems to work as I would have expected. Where I have a bigger issue is with what shows up in the actual value stored in FF. If you noticed, my change above will change the phone number value to be properly formatted as displayed within the input field...but the FF value in the debug area is still the unformatted string. Make any change to the field's value manually by interacting with the input itself, and note that both what is shown in the input and what is set within FF (displayed in the debug area) are now formatted.

@erikras I am going to try to dig a bit, but maybe you know off the top of your head - does this mean that the format prop doesn't actually change FF value, while the parse prop does?

reinrl commented 4 years ago

@erikras I can get the field to perform as expected (setting the formatted value into FF) by changing this portion of useField from:

get value() {
      let value = state.value
      if (formatOnBlur) {
        if (component === 'input') {
          value = defaultFormat(value, name)
        }
      } else {
        value = format(value, name)
      }
      if (value === null && !allowNull) {
        value = ''
      }
      if (type === 'checkbox' || type === 'radio') {
        return _value
      } else if (component === 'select' && multiple) {
        return value || []
      }
      return value
    }

to this

get value() {
      let value = state.value
      if (formatOnBlur) {
        if (component === 'input') {
          value = defaultFormat(value, name)
        }
      } else {
        value = format(value, name);
// set the formatted value into FF state as well
        state.change(value );
      }
      if (value === null && !allowNull) {
        value = ''
      }
      if (type === 'checkbox' || type === 'radio') {
        return _value
      } else if (component === 'select' && multiple) {
        return value || []
      }
      return value
    }

...but I am not sure what the other ramifications of that are (beyond some of the obvious, like unit tests that fail due to functional and/or field state differences), or if that even is the correct approach. Thoughts?

Aerendir commented 1 year ago

Any news on this?

I'm still facing the same problem: initialValues are not formatted and this forces me to format them outside the form, before passing them to it. This is really harmless, as This happens in many places and with different values and causes a lot of troubles (without mentioning being forced to cycle once more the array that contains the values for the FieldArray I'm using).