formsy-react
formsy-react copied to clipboard
Validation `values` 'undefined' with 'defaultValue' set
Hello!
So, I have a lengthy, multi-page form that I've used LocalStorage to save the state therein.
const [state, setState] = useState<AccountSetupForm>({} as AccountSetupForm)
// Load from LocalStorage on Page Load
useEffect(() => {
const savedState = window.localStorage.getItem(LSKEY_ACCOUNT_SETUP_FORM)
if (savedState) {
setState({ ...state, ...JSON.parse(savedState) })
}
}, [])
However, when I restore the state to the form (which updates its values), the validation doesn't see this.
The Next/Submit button in the form is disabled on load, even if all fields were populated on load.
const [disabled, setDisabled] = useState<boolean>(false)
return (
<Form
onValid={() => setDisabled(false)}
onInvalid={() => setDisabled(true)}
>
{/* ... */}
</Form>
)
Then, upon editing any field, only that field is defined in the validation, all else are undefined.
addValidationRule('isPhone', (values: Values, value?: string): boolean => {
console.log(values) // only the field I edited is defined, everything else is `undefined`
setState(values) // is there a better way to access the form state than inside a validator?
if (value) {
const code = values['phone-country-code']
if (code) { // <-- `code` is `undefined` even though its field has a `defaultValue`
return validator.isMobilePhone(
`${code.slice(0, code.indexOf(':'))}${value}`,
'en-US',
{
strictMode: true,
}
)
}
}
return false
})
How do I tell the validation to grab the values of all the fields after I've loaded them?
Example Form Input (for completeness of reproducability sake):
<Form.Input
autoComplete="email"
defaultValue={state.Email}
label="Email Address"
name="email"
type="email"
{/* Had to wrap this because idk how to access values except in a validator */}
validations="isEmailWrapped"
validationErrors={{
isEmail: 'Doesn\'t look like a valid email address...',
}}
errorLabel={errorLabel}
/>
If the user triggers an edit (deletes and re-types a character) in every field, then the form realizes all the inputs have values, and re-enables the Next/Submit button as expected. formsy-react is working EXCEPT for it ignoring defaultValue for initial state as mentioned above.
The input fields render with the default values, it's only the validation that is oblivious to them. to clarify.
Related to but not fixed by the steps in: #566
It is an issue of async, your form get rendered with undefined values once, then the useEffect kicks in, fills the defaultValue, but nothing update formsy about the change since defaultValue is ment to be used at the first render.
You can wait till the localStorage is loaded and re-render again.
There are 2 ways that come to mind:
- Show loading instead of the form.
- Use
keyon the form that will be related to the async operation.
const MyForm = () => {
const [state, setState] = useState<AccountSetupForm>({} as AccountSetupForm);
const [isLoaded, setLoaded] = useState(false);
// Load from LocalStorage on Page Load
useEffect(() => {
const savedState = window.localStorage.getItem(LSKEY_ACCOUNT_SETUP_FORM)
if (savedState) {
setState({ ...state, ...JSON.parse(savedState) })
setLoaded(true);
}
}, []);
return <Form
onValid={() => setDisabled(false)}
onInvalid={() => setDisabled(true)}
key={`form-${isLoaded}`} // <---
>
<Form.Input
autoComplete="email"
defaultValue={state.Email}
label="Email Address"
name="email"
type="email"
validations="isEmailWrapped"
validationErrors={{
isEmail: 'Doesn\'t look like a valid email address...',
}}
errorLabel={errorLabel}
/>
</Form>
}
@DamonBlais can we close this issue?
Sorry, that's a GitHub account I don't use often (generally by mistake.)
I'll try and login to close this.
This can be closed.
Can't find my 2fa for this
On Wed., Aug. 24, 2022, 5:41 p.m. Damon Blais, @.***> wrote:
Sorry, that's a GitHub account I don't use often (generally by mistake.)
I'll try and login to close this.
— Reply to this email directly, view it on GitHub https://github.com/formsy/formsy-react/issues/642#issuecomment-1226639191, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKTKHMIF7CR2KA2HG2E7CQDV226LNANCNFSM47LZESAA . You are receiving this because you were mentioned.Message ID: @.***>