amis-rpc-design/node_modules/rc-util/es/hooks/useMergedState.js
2023-10-07 19:42:30 +08:00

63 lines
2.1 KiB
JavaScript

import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import useEvent from "./useEvent";
import { useLayoutUpdateEffect } from "./useLayoutEffect";
import useState from "./useState";
/** We only think `undefined` is empty */
function hasValue(value) {
return value !== undefined;
}
/**
* Similar to `useState` but will use props value if provided.
* Note that internal use rc-util `useState` hook.
*/
export default function useMergedState(defaultStateValue, option) {
var _ref = option || {},
defaultValue = _ref.defaultValue,
value = _ref.value,
onChange = _ref.onChange,
postState = _ref.postState;
// ======================= Init =======================
var _useState = useState(function () {
if (hasValue(value)) {
return value;
} else if (hasValue(defaultValue)) {
return typeof defaultValue === 'function' ? defaultValue() : defaultValue;
} else {
return typeof defaultStateValue === 'function' ? defaultStateValue() : defaultStateValue;
}
}),
_useState2 = _slicedToArray(_useState, 2),
innerValue = _useState2[0],
setInnerValue = _useState2[1];
var mergedValue = value !== undefined ? value : innerValue;
var postMergedValue = postState ? postState(mergedValue) : mergedValue;
// ====================== Change ======================
var onChangeFn = useEvent(onChange);
var _useState3 = useState([mergedValue]),
_useState4 = _slicedToArray(_useState3, 2),
prevValue = _useState4[0],
setPrevValue = _useState4[1];
useLayoutUpdateEffect(function () {
var prev = prevValue[0];
if (innerValue !== prev) {
onChangeFn(innerValue, prev);
}
}, [prevValue]);
// Sync value back to `undefined` when it from control to un-control
useLayoutUpdateEffect(function () {
if (!hasValue(value)) {
setInnerValue(value);
}
}, [value]);
// ====================== Update ======================
var triggerChange = useEvent(function (updater, ignoreDestroy) {
setInnerValue(updater, ignoreDestroy);
setPrevValue([mergedValue], ignoreDestroy);
});
return [postMergedValue, triggerChange];
}