hooks.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
  2. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  3. if (ar || !(i in from)) {
  4. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  5. ar[i] = from[i];
  6. }
  7. }
  8. return to.concat(ar || Array.prototype.slice.call(from));
  9. };
  10. import { useEffect, createContext, useContext, useRef, useCallback, } from './r.js';
  11. import { instanceKeyPropNames } from './utils.js';
  12. import { checkIfPlatformIsLoadCorrectly, } from './platform.js';
  13. //@ts-expect-error
  14. function generateEventHookName(eventName) {
  15. return "use".concat(eventName[0].toUpperCase()).concat(eventName.slice(1));
  16. }
  17. export var reactContext = createContext(null);
  18. // --------------------------
  19. function useAppxContext() {
  20. var appxInstanceContext = useContext(reactContext);
  21. if (!appxInstanceContext) {
  22. throw new Error('请不要在组件内调用 hooks');
  23. }
  24. return appxInstanceContext;
  25. }
  26. function useEventCall(name, handler, disableMultiImpl) {
  27. var realHandler = useStableCallback(handler);
  28. var appxInstanceContext = useAppxContext();
  29. if (appxInstanceContext.ifServerRender) {
  30. // 虚拟渲染时,注册空实现
  31. appxInstanceContext.handlersController.addHandler(name, {}, function () { }, false);
  32. }
  33. useEffect(function () {
  34. var off = appxInstanceContext.handlersController.addHandler(name, appxInstanceContext.instance,
  35. //@ts-expect-error
  36. function () {
  37. var args = [];
  38. for (var _i = 0; _i < arguments.length; _i++) {
  39. args[_i] = arguments[_i];
  40. }
  41. return realHandler.apply(undefined, args);
  42. }, disableMultiImpl);
  43. return off;
  44. }, []);
  45. }
  46. export function useStableCallback(callback) {
  47. var fnRef = useRef();
  48. fnRef.current = callback;
  49. var memoFn = useCallback((function () {
  50. var _a;
  51. var args = [];
  52. for (var _i = 0; _i < arguments.length; _i++) {
  53. args[_i] = arguments[_i];
  54. }
  55. return (_a = fnRef.current) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spreadArray([fnRef], args, false));
  56. }), []);
  57. return memoFn;
  58. }
  59. // 注册和更新 handler,注意只能更新第一次注册过的 handler 实现,不允许变更数量和 key
  60. export function useEvent(name, handler,
  61. /**
  62. *
  63. */
  64. depsOrOptions) {
  65. var appxInstanceContext = useAppxContext();
  66. var platformConfig = appxInstanceContext.platformConfig, instance = appxInstanceContext.instance;
  67. var pageEvents = platformConfig.pageEvents, componentEvents = platformConfig.componentEvents, blockedProperty = platformConfig.blockedProperty;
  68. if (pageEvents.indexOf(name) >= 0 || componentEvents.indexOf(name) >= 0) {
  69. throw new Error("\u5C0F\u7A0B\u5E8F ".concat(name, " \u662F\u751F\u547D\u5468\u671F\u76F8\u5173\u7684\u4FDD\u7559\u65B9\u6CD5\uFF0C\u4E0D\u5141\u8BB8\u4F7F\u7528\u6B64\u79CD\u65B9\u6CD5\u6CE8\u518C\uFF0C\u8BF7\u4F7F\u7528\u5BF9\u5E94\u7684 hooks: ").concat(generateEventHookName(name)));
  70. }
  71. else if (blockedProperty.indexOf(name) >= 0) {
  72. throw new Error("\u4E0D\u5141\u8BB8\u6CE8\u518C\u540D\u4E3A ".concat(name, " \u7684\u4E8B\u4EF6\u5904\u7406\u51FD\u6570\uFF0C\u8FD9\u662F\u5C0F\u7A0B\u5E8F\u7684\u4FDD\u7559\u5C5E\u6027\uFF0C\u8BF7\u6362\u4E00\u4E2A\u540D\u79F0"));
  73. }
  74. if (Array.isArray(depsOrOptions)) {
  75. console.warn("useEventCall ".concat(name, ": hooks \u7684 deps \u5DF2\u5E9F\u5F03\uFF0C\u65E0\u9700\u586B\u5199\u3002"));
  76. }
  77. var putMethodOnData = !Array.isArray(depsOrOptions) &&
  78. (depsOrOptions === null || depsOrOptions === void 0 ? void 0 : depsOrOptions.handleResult) &&
  79. !platformConfig.supportHandleEventResult;
  80. // 对于同一个 name ,此变量永久不变,所以可以用 if else 写 hooks
  81. if (putMethodOnData) {
  82. var stableHandler_1 = useStableCallback(handler);
  83. useEffect(function () {
  84. var _a;
  85. if (instance.properties &&
  86. typeof instance.properties[name] !== 'undefined') {
  87. throw new Error("\u4E8B\u4EF6 ".concat(name, " \u6CE8\u518C\u5931\u8D25\uFF0C\u5728 handleResult \u5F00\u542F\u540E\uFF0C\u4E8B\u4EF6\u4E0D\u80FD\u540C\u65F6\u5728 properties \u4E0E useEvent \u4E2D\u5B9A\u4E49\u3002"));
  88. }
  89. instance.setData((_a = {},
  90. _a[name] = stableHandler_1,
  91. _a));
  92. }, []);
  93. }
  94. else {
  95. useEventCall(name, handler, true);
  96. }
  97. }
  98. export function getLifeCycleHooks(eventName, disableMultiImpl, specifyPlatform) {
  99. if (disableMultiImpl === void 0) { disableMultiImpl = false; }
  100. return function (handler,
  101. /**
  102. * @deprecated 无需填写依赖
  103. */
  104. deps) {
  105. var appxInstanceContext = useAppxContext();
  106. if (specifyPlatform) {
  107. var platformConfig = appxInstanceContext.platformConfig;
  108. checkIfPlatformIsLoadCorrectly(platformConfig, specifyPlatform);
  109. }
  110. useEventCall(eventName, handler, disableMultiImpl);
  111. };
  112. }
  113. export function useSyncMiniData(data) {
  114. if (data === void 0) { data = {}; }
  115. var appxInstanceContext = useAppxContext();
  116. // const propKeys = appxInstanceContext
  117. if (!appxInstanceContext.instance) {
  118. throw new Error('cannot get appx instance, failed to set data');
  119. }
  120. var lastDataRef = useRef();
  121. if (appxInstanceContext.ifServerRender) {
  122. appxInstanceContext.instance.setData(data);
  123. }
  124. var debugLog = appxInstanceContext.debugLog || function () { };
  125. if (typeof data !== 'object')
  126. throw new Error("\u51FD\u6570\u8FD4\u56DE\u7684\u6570\u636E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u6536\u5230\u4E86 ".concat(typeof data));
  127. // 这里是一个每次都要跑的 passive effect
  128. var instance = appxInstanceContext.instance;
  129. var propNames = instance[instanceKeyPropNames] || []; // 微信的 data 里包含了 props,要手动踢掉
  130. var pendingData = {};
  131. var previousData = instance.data || {};
  132. // 比对一下,只 set 不同的部分
  133. for (var key in data) {
  134. if (!Object.prototype.hasOwnProperty.call(data, key))
  135. continue;
  136. //@ts-expect-error
  137. if (typeof data[key] === 'function')
  138. throw new Error("".concat(key, " - \u4E0D\u5141\u8BB8\u4F20\u5165\u51FD\u6570\u7C7B\u578B\u7684\u6570\u636E")); // 暂不支持,有需求再说
  139. //@ts-expect-error
  140. if (!previousData[key] || previousData[key] !== data[key]) {
  141. //@ts-expect-error
  142. pendingData[key] = data[key];
  143. }
  144. if (typeof previousData[key] === 'function') {
  145. throw new Error("".concat(key, " - \u7981\u6B62\u4FEE\u6539 data \u4E0A\u5DF2\u7ECF\u5B58\u5728\u7684\u51FD\u6570"));
  146. }
  147. }
  148. // 如果之前同步过 data,但是这次没有传入,就把之前的值设置成 null
  149. // 这里用的是 lastDataRef 而不是 previousData,是因为 previousData 里可能有用户通过 this.data[key] 直接修改的值
  150. if (lastDataRef.current) {
  151. // 缺少某些 key,就设置成 null
  152. for (var _i = 0, _a = Object.keys(lastDataRef.current); _i < _a.length; _i++) {
  153. var key = _a[_i];
  154. if (propNames.indexOf(key) >= 0)
  155. continue;
  156. if (!Object.prototype.hasOwnProperty.call(data, key)) {
  157. //@ts-expect-error
  158. pendingData[key] = null;
  159. }
  160. }
  161. }
  162. if (Object.keys(pendingData).length > 0) {
  163. debugLog('calling setData', pendingData);
  164. instance.setData(pendingData);
  165. }
  166. lastDataRef.current = data;
  167. }
  168. function useMiniInstance() {
  169. var appxInstanceContext = useAppxContext();
  170. return appxInstanceContext.instance;
  171. }
  172. export var usePage = useMiniInstance;
  173. export var useComponent = useMiniInstance;