import isEqual from "lodash/isEqual"; import { Dispatch, SetStateAction, useEffect, useState } from "react"; export interface UseStateFromPropsOpts { mergeFunc?: (prevData: T, state: T, newData: T) => T; onRefresh?: (prevData: T, data: T) => void; } /** * @deprecated This function updates state every time initial * value changes, but uses deep comparisons to detect changes. * You're most likely looking for `useStateUpdate` instead. */ function useStateFromProps( data: T, opts: UseStateFromPropsOpts = {}, ): [T, Dispatch>] { const [state, setState] = useState(data); const [prevData, setPrevData] = useState(data); const { mergeFunc, onRefresh } = opts; useEffect(() => { const shouldUpdate = !isEqual(prevData, data); if (shouldUpdate) { const newData = typeof mergeFunc === "function" ? mergeFunc(prevData, state, data) : data; setState(newData); setPrevData(data); if (typeof onRefresh === "function") { onRefresh(data, newData); } } }, [data]); return [state, setState]; } export default useStateFromProps;