diff --git a/packages/inula/scripts/__tests__/ComponentTest/PortalComponent.test.js b/packages/inula/scripts/__tests__/ComponentTest/PortalComponent.test.js index 4c6924b9..98e55340 100644 --- a/packages/inula/scripts/__tests__/ComponentTest/PortalComponent.test.js +++ b/packages/inula/scripts/__tests__/ComponentTest/PortalComponent.test.js @@ -286,4 +286,98 @@ describe('PortalComponent Test', () => { dispatchChangeEvent(inputRef.current, 'test'); expect(fn).toHaveBeenCalledTimes(1); }); + + + it('portal场景下,portal下元素点击事件冒泡到父元素', () => { + class Dialog extends Inula.Component { + node; + + constructor(props) { + super(props); + this.node = window.document.createElement('div'); + window.document.body.appendChild(this.node); + } + + render() { + return Inula.createPortal(this.props.children, this.node); + } + } + + const fn = jest.fn(); + const subRef = Inula.createRef(); + + function App() { + return ( +
+ +
+
+
+ ); + } + + Inula.render(, container); + Inula.act(() => { + subRef.current.dispatchEvent(new Event('click', { bubbles: true })); + }); + expect(fn).toHaveBeenCalledTimes(1); + }); + + it('portal嵌套场景下事件委托', () => { + class Dialog extends Inula.Component { + node; + + constructor(props) { + super(props); + this.node = window.document.createElement('div'); + window.document.body.appendChild(this.node); + } + + render() { + return Inula.createPortal(this.props.children, this.node); + } + } + + const fn = jest.fn(); + const inputRef = Inula.createRef(); + let value = ''; + const onChange = (evt) => { + value = evt.target.value; + } + + let showSubPortal = () => {}; + + function App() { + return ( +
+ + + + +
+ ); + } + + function Sub() { + const [show, setShow] = Inula.useState(false); + showSubPortal = setShow; + return ( +
+ { + show && + + + + } +
+ ) + } + + Inula.render(, container); + Inula.act(() => { + showSubPortal(true); + }); + dispatchChangeEvent(inputRef.current, 'test'); + expect(value).toEqual('test'); + }); }); diff --git a/packages/inula/src/renderer/TreeBuilder.ts b/packages/inula/src/renderer/TreeBuilder.ts index 50326e25..c29126fb 100644 --- a/packages/inula/src/renderer/TreeBuilder.ts +++ b/packages/inula/src/renderer/TreeBuilder.ts @@ -244,17 +244,22 @@ export function calcStartUpdateVNode(treeRoot: VNode) { // 在局部更新时,从上到下恢复父节点的context和PortalStack function recoverTreeContext(vNode: VNode) { const contextProviders: VNode[] = []; + const portalRoots: VNode[] = []; let parent = vNode.parent; while (parent !== null) { if (parent.tag === ContextProvider) { contextProviders.unshift(parent); + } else if (parent.tag === DomPortal) { + portalRoots.unshift(parent); } if (parent.tag === DomPortal) { pushCurrentRoot(parent); } parent = parent.parent; } - + portalRoots.forEach(node => { + pushCurrentRoot(node); + }); contextProviders.forEach(node => { setContext(node, node.props.value); });