UNPKG

use-safe-force-update

Version:
127 lines (115 loc) 3.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var react = require('react'); /** * React hook for force-updating a component. * * @returns {function(): void} * Function that forces an update of the component. * @example * ```jsx * function Component() { * const values = useRef({ number: 0 }); * const forceUpdate = useForceUpdate(); * * const increaseNumber = useCallback(() => { * values.current.number++; * forceUpdate(); * }, [values, forceUpdate]); * * return ( * <> * <label children={`Increase (currently ${values.current.number})`} for='bth' /> * <button onClick={increaseNumber} id='btn' /> * </> * ) * } * ``` */ function useForceUpdate() { return react.useReducer(function () { }, undefined)[1]; } /** * React hook for force-updating a component only when mounted * (and queuing an update for when the component is mounted.) * * @returns {function(): void} * Function that attempts to force an update of the component. It also allows for queueing an update * for when the component *has* been mounted, which is simply done by calling the function * before the component has been mounted. * @example <caption>Force-updates the component immediately after being mounted./caption> * function Component() { * const forceUpdate = useMountedForceUpdate(); * * React.useMemo(() => { * forceUpdate(); * }, []); * } */ function useMountedForceUpdate() { var forceUpdate = useForceUpdate(); var lifecycle = react.useRef({ queuedUpdate: false, mounted: false, unmounted: false }); react.useEffect(function () { lifecycle.current.mounted = true; if (lifecycle.current.queuedUpdate) { lifecycle.current.queuedUpdate = false; forceUpdate(); } return function () { lifecycle.current.unmounted = true; }; }, []); return react.useCallback(function mountedForceUpdate() { if (lifecycle.current.mounted) { if (!lifecycle.current.unmounted) { forceUpdate(); } } else { lifecycle.current.queuedUpdate = true; } }, [lifecycle, forceUpdate]); } /** * React hook for force-updating a component only when it is mounted. * _**Note:** For React 18+ users, this will not be any different from `useForceUpdate`, since * there is no warning about `setState` on unmounted components._ * * @returns {function(): void} * Function that attempts to force an update of the component. * @example <caption>Forces an update after 1-10 seconds, which React will never complain about.</caption> * function Component() { * const forceUpdate = useSafeForceUpdate(); * * React.useMemo(() => { * setTimeout(() => { * forceUpdate() // React will not ever complain about this! * }, [1000 + Math.random() * 9000]) * }, []) * } */ function useSafeForceUpdate() { var forceUpdate = useForceUpdate(); var lifecycle = react.useRef({ mounted: false, unmounted: false }); react.useEffect(function () { lifecycle.current.mounted = true; return function () { lifecycle.current.unmounted = true; }; }, []); return react.useCallback(function safeForceUpdate() { if (lifecycle.current.mounted && !lifecycle.current.unmounted) { forceUpdate(); } }, [lifecycle, forceUpdate]); } exports.useForceUpdate = useForceUpdate; exports.useMountedForceUpdate = useMountedForceUpdate; exports.useSafeForceUpdate = useSafeForceUpdate;