Skip to content

Commit

Permalink
fix: 🐛 Only resets form data after success if async
Browse files Browse the repository at this point in the history
  • Loading branch information
aviemet committed Mar 24, 2023
1 parent 6f45998 commit 3f970c7
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 23 deletions.
25 changes: 13 additions & 12 deletions src/Form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect } from 'react'
import axios from 'axios'
import { type Visit } from '@inertiajs/core'
import { type VisitOptions } from '@inertiajs/core'
import useInertiaForm, { NestedObject } from '../useInertiaForm'
import { useForm, type UseFormProps, type HTTPVerb, FormProvider } from './FormProvider'
import FormMetaWrapper, { useFormMeta, type FormMetaValue } from './FormMetaWrapper'
Expand All @@ -13,6 +13,7 @@ export interface FormProps<TForm> extends PartialHTMLForm {
method?: HTTPVerb
to?: string
async?: boolean
resetAfterSubmit?: boolean
remember?: boolean
railsAttributes?: boolean
onSubmit?: (form: UseFormProps<TForm>) => boolean|void
Expand All @@ -28,25 +29,25 @@ const Form = <TForm extends NestedObject>({
method = 'post',
to,
async = false,
resetAfterSubmit,
remember = true,
onSubmit,
onChange,
onSuccess,
onError,
...props
}: Omit<FormProps<TForm>, 'railsAttributes'>) => {

const form = remember && (model || to) ? useInertiaForm<TForm>(`${method}/${model || to}`, data) : useInertiaForm<TForm>(data)

const contextValueObject = useCallback((): UseFormProps<TForm> => (
{ ...form, model, method, to, submit }
), [form.data, form.errors])
), [data, form.data, form.errors])

/**
* Submits the form. If async prop is true, submits using axios,
* otherwise submits using Inertia's `useForm.submit` method
*/
const submit = async (options?: Partial<Visit>) => {
const submit = async (options?: Partial<VisitOptions>) => {
let shouldSubmit = to && onSubmit && onSubmit(contextValueObject()) === false ? false : true

if(shouldSubmit) {
Expand All @@ -62,7 +63,14 @@ const Form = <TForm extends NestedObject>({
e.preventDefault()
e.stopPropagation()

submit()
submit({
onSuccess: () => {
if(resetAfterSubmit || (resetAfterSubmit !== false && async === true)) {
form.reset()
}
if(onSuccess) onSuccess(contextValueObject())
},
})
}

// Set values from url search params. Allows for prefilling form data from a link
Expand All @@ -82,13 +90,6 @@ const Form = <TForm extends NestedObject>({
if(onError) onError(contextValueObject())
}, [form.errors])

useEffect(() => {
if(!form.wasSuccessful) return

form.reset()
if(onSuccess) onSuccess(contextValueObject())
}, [form.wasSuccessful])

return (
<FormProvider value={ contextValueObject() }>
<form onSubmit={ handleSubmit } { ...props }>
Expand Down
4 changes: 2 additions & 2 deletions src/Inputs/Submit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const Submit = React.forwardRef<HTMLButtonElement, ButtonProps>((
{ children, type = 'submit', disabled, component = 'button', ...props },
ref,
) => {
const { processing } = useForm()
const { processing, isDirty } = useForm()

const finalProps = { children, type, disabled: disabled || processing, ref, ...props }
const finalProps = { children, type, disabled: disabled || processing || !isDirty, ref, ...props }

if(typeof component === 'string') {
return React.createElement(component, finalProps)
Expand Down
21 changes: 13 additions & 8 deletions src/useInertiaForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,20 @@ export default function useInertiaForm<TForm>(
const isMounted = useRef<boolean>()

// Data
let rememberKey = null
let transformedData = rememberKeyOrInitialValues
if(typeof rememberKeyOrInitialValues === 'string') {
rememberKey = rememberKeyOrInitialValues
transformedData = maybeInitialValues
}
const getFormArguments = useCallback((): [string, TForm] => {
let rememberKey: string = null
let transformedData = rememberKeyOrInitialValues
if(typeof rememberKeyOrInitialValues === 'string') {
rememberKey = rememberKeyOrInitialValues
transformedData = maybeInitialValues
}
return [rememberKey, fillEmptyValues(transformedData as TForm)]
}, [rememberKeyOrInitialValues, maybeInitialValues])

const [rememberKey, transformedData] = getFormArguments()

const [defaults, setDefaults] = useState((fillEmptyValues(transformedData) || {}) as TForm)
const [data, setData] = rememberKey ? useRemember<TForm>(defaults, `${rememberKey}:data`) : useState<TForm>(defaults)
const [defaults, setDefaults] = useState(transformedData || {} as TForm)
const [data, setData] = rememberKey ? useRemember<TForm>(transformedData, `${rememberKey}:data`) : useState<TForm>(transformedData)

// Errors
const [errors, setErrors] = rememberKey
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"target": "ESNext",
"module": "esnext",
"lib": ["dom", "esnext"],
"lib": ["dom", "esnext", "dom.iterable"],
"jsx": "react",
"declaration": true,
"sourceMap": true,
Expand Down

0 comments on commit 3f970c7

Please sign in to comment.