useMixState.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { useEvent } from './useEvent';
  2. import { useComponentUpdateEffect } from './useLayoutEffect';
  3. import { hasValue } from './useMergedState';
  4. import { useSafeState as useState } from './useState';
  5. export function useMixState(defaultStateValue, option) {
  6. var _a = option || {}, defaultValue = _a.defaultValue, value = _a.value, _b = _a.postState, postState = _b === void 0 ? function (v) { return ({ valid: true, value: v }); } : _b;
  7. // ======================= Init =======================
  8. var _c = useState(function () {
  9. var v;
  10. if (hasValue(value)) {
  11. v = value;
  12. }
  13. else if (hasValue(defaultValue)) {
  14. v =
  15. typeof defaultValue === 'function'
  16. ? defaultValue()
  17. : defaultValue;
  18. }
  19. else {
  20. v =
  21. typeof defaultStateValue === 'function'
  22. ? defaultStateValue()
  23. : defaultStateValue;
  24. }
  25. var state = postState(v);
  26. if (state.valid) {
  27. return state.value;
  28. }
  29. }), innerValue = _c[0], setInnerValue = _c[1];
  30. var state = postState(value);
  31. var merge = hasValue(value) && state.valid ? state.value : innerValue;
  32. useComponentUpdateEffect(function () {
  33. var state = postState(value);
  34. if (state.valid) {
  35. setInnerValue(state.value);
  36. }
  37. }, [value]);
  38. var isControlled = hasValue(value);
  39. var triggerChange = useEvent(function (newState, ignoreDestroy) {
  40. setInnerValue(newState, ignoreDestroy);
  41. });
  42. var triggerUpdate = useEvent(function (value, option) {
  43. var state = postState(value, option);
  44. if (state.valid && state.value !== innerValue) {
  45. triggerChange(state.value);
  46. return { changed: true, newValue: state.value };
  47. }
  48. return { changed: false };
  49. });
  50. var triggerUpdater = useEvent(function (getValue, option) {
  51. if (isControlled) {
  52. getValue(merge);
  53. }
  54. else {
  55. triggerChange(function (old) {
  56. var newValue = getValue(old);
  57. var state = postState(newValue, option);
  58. if (state.valid && state.value !== innerValue) {
  59. return state.value;
  60. }
  61. return old;
  62. });
  63. }
  64. });
  65. return [
  66. merge,
  67. {
  68. isControlled: isControlled,
  69. update: triggerUpdate,
  70. triggerUpdater: triggerUpdater,
  71. },
  72. ];
  73. }