Debounce API requests on edit nym by 500ms (#387)

Support an optional debounce prop on Input component

If provided, the debounce is applied to the validation of the containing form,
imperatively invoking form validation after debounce is finalized

Also required introducing the `validateOnChange` prop on `Form` which gets passed to `Formik`, and defaults to true, just as it does in `Formik`.

Imperatively invoking form validation seemed to be the only way to debounce the validation call through formik.
This commit is contained in:
SatsAllDay 2023-08-09 18:06:22 -04:00 committed by GitHub
parent 0fb1bf7095
commit d5f7855adf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 2 deletions

View File

@ -219,7 +219,7 @@ function FormGroup ({ className, label, children }) {
function InputInner ({
prepend, append, hint, showValid, onChange, overrideValue,
innerRef, noForm, clear, onKeyDown, ...props
innerRef, noForm, clear, onKeyDown, debounce, ...props
}) {
const [field, meta, helpers] = noForm ? [{}, {}, {}] : useField(props)
const formik = noForm ? null : useFormikContext()
@ -245,6 +245,18 @@ function InputInner ({
const invalid = (!formik || formik.submitCount > 0) && meta.touched && meta.error
const debounceRef = useRef(-1)
useEffect(() => {
if (debounceRef.current !== -1) {
clearTimeout(debounceRef.current)
}
if (!noForm && !isNaN(debounce) && debounce > 0) {
debounceRef.current = setTimeout(() => formik.validateForm(), debounce)
}
return () => clearTimeout(debounceRef.current)
}, [noForm, formik, field.value])
return (
<>
<InputGroup hasValidation>
@ -446,13 +458,14 @@ export function Checkbox ({ children, label, groupClassName, hiddenLabel, extra,
const StorageKeyPrefixContext = createContext()
export function Form ({
initial, schema, onSubmit, children, initialError, validateImmediately, storageKeyPrefix, ...props
initial, schema, onSubmit, children, initialError, validateImmediately, storageKeyPrefix, validateOnChange = true, ...props
}) {
const [error, setError] = useState(initialError)
return (
<Formik
initialValues={initial}
validateOnChange={validateOnChange}
validationSchema={schema}
initialTouched={validateImmediately && initial}
validateOnBlur={false}

View File

@ -111,6 +111,7 @@ function NymEdit ({ user, setEditting }) {
name: user.name
}}
validateImmediately
validateOnChange={false}
onSubmit={async ({ name }) => {
if (name === user.name) {
setEditting(false)
@ -137,6 +138,7 @@ function NymEdit ({ user, setEditting }) {
autoFocus
groupClassName={styles.usernameForm}
showValid
debounce={500}
/>
<SubmitButton variant='link' onClick={() => setEditting(true)}>save</SubmitButton>
</div>