Files
sk-react-toolkit/web/useValidation.ts
T

27 lines
1.2 KiB
TypeScript

import { useEffect, useState } from 'react'
import { request, type Validation } from './api.ts'
/**
* Asks the server to validate value at path (a .../validate endpoint) 250 ms after it last
* changed. pending is true until the answer for the current value arrives; until then the previous result stays.
*/
export function useValidation<T extends Validation>(path: string | null, value: unknown): { result: T | null; error: string; pending: boolean } {
const key = path === null ? '' : `${path}\n${JSON.stringify(value)}`
const [answer, setAnswer] = useState<{ key: string; result: T | null; error: string } | null>(null)
useEffect(() => {
if (key === '') {
return
}
const [target, body] = [key.slice(0, key.indexOf('\n')), JSON.parse(key.slice(key.indexOf('\n') + 1))]
const timer = window.setTimeout(() => {
request<T>('POST', target, { value: body })
.then((result) => setAnswer({ key, result, error: '' }))
.catch((caught: Error) => setAnswer({ key, result: null, error: caught.message }))
}, 250)
return () => window.clearTimeout(timer)
}, [key])
return { result: answer?.result ?? null, error: answer?.error ?? '', pending: key !== '' && answer?.key !== key }
}