remix-hook-form
remix-hook-form copied to clipboard
Cannot clear custom errors when returned by the server
Hello, thanks for the library! Got a small issue
When i'm returning a custom error from the action as following:
export async function action({request, context, params}: ActionArgs) {
const {
data,
errors,
receivedValues ,
} = await getValidatedFormData(request, zodResolver(createSpaceInput))
try {
const result = context.api.onboarding.setUpSpace.mutate({
name: data.name
})
return json({ space: result })
} catch(e) {
return json({
errors: {
root: {
message: e.message
}
}
})
}
}
The error can be displayed just fine.
However, when i try to clear the error for example onChange it simply doesn't clear.
const form = useRemixForm({
mode: "onSubmit",
defaultValues: {
name: "",
},
resolver: zodResolver(formSchema),
});
<RemixForm onSubmit={form.handleSubmit} method={"POST"} onChange={() => {
console.log('form on change', form.formState.errors)
form.clearErrors('root')
}}>
I have also noticed that when I return an error which has the same name as one of the fields:
export async function action({request, context, params}: ActionArgs) {
... // rest of the function
return json({
errors: {
name: {
message: 'some backend error coming from external api'
}
}
})
}
It behaves the same way, as in the message is shown just fine, but it can't be cleared up
Any tips?
@fenos Hello! The issue you're facing is the fact that when you return the remix errors from the backend they are consumed internally by the hook until they are cleared in the useActionData (eg you submit again). This means that there is no way to remove the errors via form.clearErrors, but this should not indeed be the case but should be cleared. I will make a patch for this when I get the time and this behavior should remove it so this is definitely not the way it should work. Until then I could recommend that you check if the error that comes from the hook is the same as the be one and clear it like that by using useActionData and handling the errors that way
Any progress on this? I have just come across the same issue. If you have a recommend solution I can implement it for you.
Any progress on this? I have just come across the same issue. If you have a recommend solution I can implement it for you.
@Centerworx i think the solution is to have a simple setState that is set to true on submit and false on reset and depending on that it consumes the be errors
@AlemTuzlak Working on it. There is an issue around useActionData return the value before submit true is set. Even though it is set to true before calling submit handler. But this may just be test implementation issue.
@AlemTuzlak I have the fix done and tested. I'm having an issue pushing it. Problem with my git.
Hi, first of all, thanks to @AlemTuzlak for making remix-hook-form. I used usePrevious in the project to get the difference of serverErrors and then merged it, which temporarily solved the problem.
const errors = data?.errors || emptyErrors
const [serverErrors, setServerErrors] = React.useState(() => errors)
const previousServerErrors = usePrevious(serverErrors)
const formErrors = React.useMemo(() => {
const keys = Object.keys(serverErrors)
const prevKeys = previousServerErrors ? Object.keys(previousServerErrors) : []
const deletedErrorKeys = prevKeys.filter((key) => !keys.includes(key))
const localErrors = methods.formState.errors as FieldErrors<Output>
const mergedErrors = mergeErrors<Output>(localErrors, serverErrors, validKeys)
for (const key of deletedErrorKeys) {
delete mergedErrors[key]
}
return mergedErrors
}, [methods.formState.errors, previousServerErrors, serverErrors, validKeys])
React.useEffect(() => {
if (isSubmitting) {
setServerErrors(emptyErrors)
} else {
// Only update the server errors if the form is not submitting
setServerErrors(errors)
}
}, [errors, isSubmitting])
Is there any progress on this? I just run into the same issue.
So this might be potentially fixed with the fact that I moved to using the react-hook-form native "errors" prop, can anyone confirm?