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:
parent
0fb1bf7095
commit
d5f7855adf
|
@ -219,7 +219,7 @@ function FormGroup ({ className, label, children }) {
|
||||||
|
|
||||||
function InputInner ({
|
function InputInner ({
|
||||||
prepend, append, hint, showValid, onChange, overrideValue,
|
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 [field, meta, helpers] = noForm ? [{}, {}, {}] : useField(props)
|
||||||
const formik = noForm ? null : useFormikContext()
|
const formik = noForm ? null : useFormikContext()
|
||||||
|
@ -245,6 +245,18 @@ function InputInner ({
|
||||||
|
|
||||||
const invalid = (!formik || formik.submitCount > 0) && meta.touched && meta.error
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<InputGroup hasValidation>
|
<InputGroup hasValidation>
|
||||||
|
@ -446,13 +458,14 @@ export function Checkbox ({ children, label, groupClassName, hiddenLabel, extra,
|
||||||
const StorageKeyPrefixContext = createContext()
|
const StorageKeyPrefixContext = createContext()
|
||||||
|
|
||||||
export function Form ({
|
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)
|
const [error, setError] = useState(initialError)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={initial}
|
initialValues={initial}
|
||||||
|
validateOnChange={validateOnChange}
|
||||||
validationSchema={schema}
|
validationSchema={schema}
|
||||||
initialTouched={validateImmediately && initial}
|
initialTouched={validateImmediately && initial}
|
||||||
validateOnBlur={false}
|
validateOnBlur={false}
|
||||||
|
|
|
@ -111,6 +111,7 @@ function NymEdit ({ user, setEditting }) {
|
||||||
name: user.name
|
name: user.name
|
||||||
}}
|
}}
|
||||||
validateImmediately
|
validateImmediately
|
||||||
|
validateOnChange={false}
|
||||||
onSubmit={async ({ name }) => {
|
onSubmit={async ({ name }) => {
|
||||||
if (name === user.name) {
|
if (name === user.name) {
|
||||||
setEditting(false)
|
setEditting(false)
|
||||||
|
@ -137,6 +138,7 @@ function NymEdit ({ user, setEditting }) {
|
||||||
autoFocus
|
autoFocus
|
||||||
groupClassName={styles.usernameForm}
|
groupClassName={styles.usernameForm}
|
||||||
showValid
|
showValid
|
||||||
|
debounce={500}
|
||||||
/>
|
/>
|
||||||
<SubmitButton variant='link' onClick={() => setEditting(true)}>save</SubmitButton>
|
<SubmitButton variant='link' onClick={() => setEditting(true)}>save</SubmitButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue