react-spectrum
react-spectrum copied to clipboard
[NumberField] Setting null to value does not reset to blank state
๐ Bug Report
When using the NumberField component, if the implementor wants to use a controlled state to control the value of NumberField, passing in null does not reset this component to the initial state.
๐ค Expected Behavior
- Passing null should reset to the empty state for this component
๐ฏ Current Behavior
- Passing null sets the value to 0.
๐ Possible Solution
Update https://github.com/adobe/react-spectrum/blob/main/packages/@react-stately/numberfield/src/useNumberFieldState.ts#L91 so it retains the empty state if the component is used in a controlled state.
๐ฆ Context
- If we have external logic using react-hook-form to control this component, we want to be able to reset the
NumberFieldcomponent to its initial case. A use case for example, for form validation. If user resets the form and we have a parentFormcomponent that holds all the values of the form components, we want to reset it to the original empty value. - Currently, by passing in
nulltovalueprop would result in 0, which can be a valid value and does not tell the implementor that user has not filled this form from looking at the value. If we pass inundefined, it looks like theNumberFieldretains the previous value. (eg. user enters 5, then hits reset button which results in passingundefinedto thevalueprop, the value shown is 5 still)
๐ป Code Sample
https://codesandbox.io/s/nice-moore-ochpe?file=/src/App.js
๐ Your Environment
| Software | Version(s) |
|---|---|
| react-spectrum | 3.13.0 |
| Browser | Chrome Version 92.0.4515.107 |
| Operating System | macOS BigSur v11.4 |
๐งข Your Company/Team
Adobe/quarry
๐ท Tracking Issue (optional)
@LFDanLu - sorry I couldn't directly assign to you. Pinging you in comment and leaving a comment in our Slack thread as well. Thanks again!
Another line of interest: https://github.com/adobe/react-spectrum/blob/main/packages/@react-stately/numberfield/src/useNumberFieldState.ts#L108
IMO we should check if numberValue == null and call setInputValue with to "" in that case perhaps
We'll also need to check for other areas where we do a similar NaN check and account for those as well.
Is there a workaround for this?
At the moment none that I know of, short of using something like patch package to patch the bug locally.
EDIT:
@snowystinger has reminded me that you can use NaN instead of null here to properly clear the value within the NumberField for now.
This is also an issue with the datePicker component see https://github.com/adobe/react-spectrum/issues/3187. I don't think there is an equivalent NaN workaround for this component either.
I noticed the previous way to update a controlled value is via a useEffect hook but now it's changed to
if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {
setInputValue(format(numberValue));
// ...
}
Looks like we can solve the problem by simply adding a sanity check in L97
let format = useCallback((value: number) => isNaN(value) ? '' : formatter.format(value), [formatter]);
===>
let format = useCallback((value: number) => (isNaN(value) || value === null) ? '' : formatter.format(value), [formatter]);