diff --git a/libs/horizon/index.ts b/libs/horizon/index.ts index c11b255a..05aa5d6f 100644 --- a/libs/horizon/index.ts +++ b/libs/horizon/index.ts @@ -32,6 +32,7 @@ import { callRenderQueueImmediate } from './src/renderer/taskExecutor/RenderQueu import { runAsyncEffects } from './src/renderer/submit/HookEffectHandler'; import { isContextProvider, + isContextConsumer, isElement, isForwardRef, isFragment, @@ -101,7 +102,8 @@ const Horizon = { isLazy, isMemo, isPortal, - isContextProvider + isContextProvider, + isContextConsumer }; export const version = __VERSION__; @@ -149,7 +151,8 @@ export { isLazy, isMemo, isPortal, - isContextProvider + isContextProvider, + isContextConsumer }; export default Horizon; diff --git a/libs/horizon/src/external/HorizonIs.ts b/libs/horizon/src/external/HorizonIs.ts index fb666530..e2301e9e 100644 --- a/libs/horizon/src/external/HorizonIs.ts +++ b/libs/horizon/src/external/HorizonIs.ts @@ -13,10 +13,18 @@ import { TYPE_SUSPENSE, } from './JSXElementType'; -function isObject(i) { - return Object.prototype.toString.call(i) === '[object Object]'; +function isObject(anyThing) { + return Object.prototype.toString.call(anyThing) === '[object Object]'; } +/** + * 获取传入的element的类型 + * 1. fragment, suspense 属于内置标签,类型位于type + * 2. memo, lazy, forwardRef 属于包装函数,产生新的对象,类型位于type.vtype + * 3. Context.Provider/Consumer 的类型是框架定义的对象,类型位于type.vtype + * 4. portal比较特殊,函数结果直接可以作为element,类型位于vtype + * @param ele + */ function getType(ele: any) { if (isObject(ele)) { const type = ele.type; @@ -25,12 +33,12 @@ function getType(ele: any) { } const vtypeOfType = type?.vtype; - if ([TYPE_PROVIDER, TYPE_LAZY, TYPE_FORWARD_REF, TYPE_CONTEXT].includes(vtypeOfType)) { + if ([TYPE_MEMO, TYPE_PROVIDER, TYPE_LAZY, TYPE_FORWARD_REF, TYPE_CONTEXT].includes(vtypeOfType)) { return vtypeOfType; } const vtype = ele.vtype; - if([TYPE_MEMO, TYPE_FORWARD_REF, TYPE_PORTAL].includes(vtype)) { + if(TYPE_PORTAL === vtype) { return vtype; } } @@ -65,3 +73,8 @@ export function isPortal(ele: any) { export function isContextProvider(ele: any) { return getType(ele) === TYPE_PROVIDER; } + +// Context.consumer的类型就是context的类型 +export function isContextConsumer(ele: any) { + return getType(ele) === TYPE_CONTEXT; +} diff --git a/scripts/__tests__/HorizonIsTest/index.test.js b/scripts/__tests__/HorizonIsTest/index.test.js index 5a4b47e1..0fe87e87 100644 --- a/scripts/__tests__/HorizonIsTest/index.test.js +++ b/scripts/__tests__/HorizonIsTest/index.test.js @@ -31,8 +31,8 @@ describe('HorizonIs', () => { }); it('should identify memo component', () => { - const memo = Horizon.memo(App); - expect(Horizon.isMemo(memo)).toBe(true); + const MemoComp = Horizon.memo(App); + expect(Horizon.isMemo()).toBe(true); }); it('should identify forwardRef', () => { @@ -54,5 +54,7 @@ describe('HorizonIs', () => { const TestContext = Horizon.createContext(false); expect(Horizon.isContextProvider()).toBe(true); expect(Horizon.isContextProvider()).toBe(false); + expect(Horizon.isContextConsumer()).toBe(false); + expect(Horizon.isContextConsumer()).toBe(true); }); });