diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index c8b81ae7..683c9bc3 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -199,6 +199,10 @@ export function calcStartUpdateVNode(treeRoot: VNode) { for (let i = 1; i < startNodePath.length; i++) { const pathIndex = Number(startNodePath[i]); node = getChildByIndex(node, pathIndex)!; + // 路径错误时,回退到从根更新 + if (node == null) { + return treeRoot; + } } return node; diff --git a/libs/horizon/src/renderer/render/LazyComponent.ts b/libs/horizon/src/renderer/render/LazyComponent.ts index 7f81ab2a..27feb0af 100644 --- a/libs/horizon/src/renderer/render/LazyComponent.ts +++ b/libs/horizon/src/renderer/render/LazyComponent.ts @@ -61,6 +61,7 @@ function captureLazyComponent( if (lazyRender) { if (lazyVNodeTag === MemoComponent) { // Memo要特殊处理 + processing.effectList = null; const memoVNodeProps = mergeDefaultProps(Component.type, lazyVNodeProps); // 需要整合defaultProps return lazyRender(processing, Component, memoVNodeProps, shouldUpdate); } else { diff --git a/scripts/__tests__/ComponentTest/ForwardRef.test.js b/scripts/__tests__/ComponentTest/ForwardRef.test.js new file mode 100644 index 00000000..993d800a --- /dev/null +++ b/scripts/__tests__/ComponentTest/ForwardRef.test.js @@ -0,0 +1,45 @@ +import * as Horizon from '@cloudsop/horizon/index.ts'; +import { getLogUtils } from '../jest/testUtils'; + +describe('ForwardRef', () => { + const LogUtils = getLogUtils(); + it('ForwardRef包裹的函数组件应该正常触发effect', () => { + function App(props, ref) { + Horizon.useEffect(() => { + LogUtils.log('effect'); + return () => { + LogUtils.log('effect remove'); + }; + }); + return ; + } + + const Wrapper = Horizon.forwardRef(App); + + Horizon.act(() => { + Horizon.render(, container); + }); + expect(LogUtils.getAndClear()).toEqual(['effect']); + Horizon.act(() => { + Horizon.render(, container); + }); + expect(LogUtils.getAndClear()).toEqual(['effect remove', 'effect']); + }); + + it('memo组件包裹的类组件', () => { + class Component extends Horizon.Component { + render() { + return ; + } + } + + const Wrapper = Horizon.memo(Component); + + Horizon.act(() => { + Horizon.render(, container); + }); + Horizon.act(() => { + Horizon.render(, container); + }); + }); +}); diff --git a/scripts/__tests__/ComponentTest/LazyComponent.test.js b/scripts/__tests__/ComponentTest/LazyComponent.test.js index 704dca45..b59c7805 100755 --- a/scripts/__tests__/ComponentTest/LazyComponent.test.js +++ b/scripts/__tests__/ComponentTest/LazyComponent.test.js @@ -184,4 +184,30 @@ describe('LazyComponent Test', () => { container.querySelector('button').click(); expect(container.textContent).toBe('Error: num is 2'); }); + + it('#24 配合memo', async () => { + const fnComp = () => { + return

horizon

; + }; + const LazyApp = Horizon.lazy(() => ({ + then(cb) { + cb({ default: Horizon.memo(() => fnComp, false) }); + }, + })); + expect(() => { + Horizon.render( + Loading...}> + + , + container + ); + + Horizon.render( + Loading...}> + + , + container + ); + }).not.toThrow(); + }); }); diff --git a/scripts/rollup/rollup.config.js b/scripts/rollup/rollup.config.js index c3c31b49..290490e5 100644 --- a/scripts/rollup/rollup.config.js +++ b/scripts/rollup/rollup.config.js @@ -23,7 +23,8 @@ if (!fs.existsSync(outDir)) { const outputResolve = (...p) => path.resolve(outDir, ...p); function genConfig(mode) { - const sourcemap = mode === 'development' ? 'inline' : false; + const isDev = mode === 'development'; + const sourcemap = isDev ? 'inline' : false; return { input: path.resolve(libDir, 'index.ts'), output: [ @@ -53,7 +54,8 @@ function genConfig(mode) { replace({ values: { 'process.env.NODE_ENV': `"${mode}"`, - isDev: 'true', + isDev: isDev.toString(), + isTest: false, __VERSION__: `"${horizonVersion}"`, }, preventAssignment: true,