63 lines
2.1 KiB
JavaScript
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];
|
|
} |