2021-05-14 08:15:15 +00:00
|
|
|
import isEqual from "lodash/isEqual";
|
2022-05-05 07:54:28 +00:00
|
|
|
import { Dispatch, SetStateAction, useEffect, useState } from "react";
|
2019-08-09 10:17:04 +00:00
|
|
|
|
|
|
|
export interface UseStateFromPropsOpts<T> {
|
|
|
|
mergeFunc?: (prevData: T, state: T, newData: T) => T;
|
2022-05-05 07:54:28 +00:00
|
|
|
onRefresh?: (prevData: T, data: T) => void;
|
2019-08-09 10:17:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function useStateFromProps<T>(
|
|
|
|
data: T,
|
2022-05-05 07:54:28 +00:00
|
|
|
opts: UseStateFromPropsOpts<T> = {}
|
2019-08-09 10:17:04 +00:00
|
|
|
): [T, Dispatch<SetStateAction<T>>] {
|
|
|
|
const [state, setState] = useState(data);
|
|
|
|
const [prevData, setPrevData] = useState(data);
|
|
|
|
|
|
|
|
const { mergeFunc, onRefresh } = opts;
|
|
|
|
|
2022-05-05 07:54:28 +00:00
|
|
|
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);
|
|
|
|
}
|
2019-08-09 10:17:04 +00:00
|
|
|
}
|
2022-05-05 07:54:28 +00:00
|
|
|
}, [data]);
|
2019-08-09 10:17:04 +00:00
|
|
|
|
|
|
|
return [state, setState];
|
|
|
|
}
|
|
|
|
|
|
|
|
export default useStateFromProps;
|