useMergedState.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /**
  2. * copy from https://github.com/react-component/util/blob/9d5cb8946da29e690bead78b2c251da6f7cbd0eb/src/hooks/useMergedState.ts
  3. */
  4. import { useEvent } from './useEvent';
  5. import { useComponentUpdateEffect } from './useLayoutEffect';
  6. import { useSafeState as useState } from './useState';
  7. import { supportUndefinedProperty } from '../platform';
  8. /** We only think `undefined` is empty */
  9. export function hasValue(value) {
  10. if (supportUndefinedProperty()) {
  11. return value !== undefined;
  12. }
  13. return value !== null && value !== undefined;
  14. }
  15. /**
  16. * Similar to `useState` but will use props value if provided.
  17. * Note that internal use rc-util `useState` hook.
  18. */
  19. export function useMergedState(defaultStateValue, option) {
  20. var _a = option || {}, defaultValue = _a.defaultValue, value = _a.value, onChange = _a.onChange, postState = _a.postState;
  21. // ======================= Init =======================
  22. var _b = useState(function () {
  23. if (hasValue(value)) {
  24. return value;
  25. }
  26. else if (hasValue(defaultValue)) {
  27. return typeof defaultValue === 'function'
  28. ? defaultValue()
  29. : defaultValue;
  30. }
  31. else {
  32. return typeof defaultStateValue === 'function'
  33. ? defaultStateValue()
  34. : defaultStateValue;
  35. }
  36. }), innerValue = _b[0], setInnerValue = _b[1];
  37. var mergedValue = hasValue(value) ? value : innerValue;
  38. var postMergedValue = postState ? postState(mergedValue) : mergedValue;
  39. // ====================== Change ======================
  40. var onChangeFn = useEvent(onChange);
  41. var _c = useState([mergedValue]), prevValue = _c[0], setPrevValue = _c[1];
  42. useComponentUpdateEffect(function () {
  43. var prev = prevValue[0];
  44. if (innerValue !== prev) {
  45. onChangeFn(innerValue, prev);
  46. }
  47. }, [prevValue]);
  48. // Sync value back to `undefined` when it from control to un-control
  49. useComponentUpdateEffect(function () {
  50. if (!hasValue(value)) {
  51. setInnerValue(value);
  52. }
  53. }, [value]);
  54. // ====================== Update ======================
  55. var triggerChange = useEvent(function (updater, ignoreDestroy) {
  56. setInnerValue(updater, ignoreDestroy);
  57. setPrevValue([mergedValue], ignoreDestroy);
  58. });
  59. return [postMergedValue, triggerChange];
  60. }