final-form / react-final-form

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

Radio buttons stringify object values when clicked #917

Open David-Nickerson-bhnetwork opened 3 years ago

David-Nickerson-bhnetwork commented 3 years ago

Are you submitting a bug report or a feature request?

Bug report

What is the current behavior?

If a radio button's value property is an object, then clicking that radio button will cause the string "[object Object]" to be stored to the form values.

What is the expected behavior?

The FieldProps documentation states that the value property may be any type for checkboxes and radio buttons. I would expect that the object should be stored to the form without being converted to a string.

Sandbox Link

https://codesandbox.io/s/react-final-form-radio-object-values-bug-c927j?file=/index.js

What's your environment?

node: 14.16.1 react: 16.14.0 final-form: 4.20.2 react-final-form: 6.5.3 OS: macOS 10.14.6 Browser: Chrome 90.0.4430.212

Other information

The initial value and value comparison works properly. The bug is only triggered when the selected radio button changes.

David-Nickerson-bhnetwork commented 3 years ago

If anyone is looking for a workaround, you can create a lookup table:

const larryObject = { name: "larry" };
const moeObject = { name: "moe" };
const curlyObject = { name: "curly" };

const stoogeLookup = {
  larry: larryObject,
  moe: moeObject,
  curly: curlyObject
};

And use the parse and format properties to convert between strings and objects:

<Field
  name="stooge"
  component="input"
  type="radio"
  value={larryObject.name}
  parse={(stoogeName) => stoogeLookup[stoogeName]}
  format={(stooge) => stooge.name}
/>

Note that initialValues should be passed the object while value should be passed the string.

https://codesandbox.io/s/react-final-form-radio-object-values-bug-workaround-cgpbc?file=/index.js

Depending on your use case, you may not need the lookup table if you can return the desired object in the parse function:

parse={() => larryObject}

Note that the format function may be passed the value from any of the radio buttons, so format={() => larryObject.name} would not provide the expected result.

leonardopolly commented 3 years ago

I'm having the same problem. It's very weird that such a popular form tool doesn't allow us to put non-string values on radio fields. I'm trying to have true/false radio button, but apparently I can only do it with a checkbox

callmeberzerker commented 3 years ago

That's all on the DOM and html that allow only value for type="radio" to be of value string. 🤷

I think react-final-form tries to do its best if you set type="radio".