Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 5x 136x 136x 136x 28x 28x 28x 28x 28x 10x 10x 10x 10x 5x 5x 5x 28x 136x 57x 57x 136x 136x 49x 49x 136x 136x 136x 136x 136x | import {useCallback, useEffect, useRef} from 'react' import createIterableResult from "./createIterableResult" import useResource from "./useResource" import createControllablePromise from "./createControllablePromise" import createAbortController from "./createAbortController" const useFetchCallback = (fetcher, defaultResource = {}) => { let abortController = createAbortController() const [resource, setResource] = useResource(defaultResource) let callback = (...args) => { abortController = createAbortController() const {promise, resolve, reject} = createControllablePromise() const {signal} = abortController setResource({loading: true, error: null, data: null}) fetcher(...args, signal).then((data) => { resolve(data) //gives the ability to set some state before loading is changed (useful in pessimistic update example) promise.then(() => { Eif (!signal.aborted) { setResource({loading: false, error: null, data}) } }) }).catch((error) => { reject(error) Eif (error?.name !== 'AbortError') { setResource({loading: false, error, data: null}) } }) return promise } callback.abort = () => { setResource({loading: false, error: null, data: null}) abortController.abort() } const memoCallback = useCallback(callback, [fetcher]) useEffect(() => { return () => { memoCallback.abort() } }, [memoCallback]) let resultRef = useRef(createIterableResult()) resultRef.current.callback = memoCallback resultRef.current.resource = resource resultRef.current.setResource = setResource return resultRef.current } export default useFetchCallback |