From e1f0d3f3a89bf535ac79ed9f1cb5ba50397a079a Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 25 Sep 2020 13:11:45 +0800 Subject: [PATCH 1/4] chore: Not trigger getContainer when dom not ready --- src/index.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 17569fc6..baaa732e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -540,10 +540,17 @@ export function generateTrigger( }; attachParent = (popupContainer: HTMLDivElement) => { - const { props } = this; - const mountNode = props.getPopupContainer - ? props.getPopupContainer(this.getRootDomNode()) - : props.getDocument().body; + const { getPopupContainer, getDocument } = this.props; + const domNode = this.getRootDomNode(); + + let mountNode: HTMLElement; + if (!getPopupContainer) { + mountNode = getDocument().body; + } else if (domNode) { + // Compatible for sync render usage + // https://codesandbox.io/s/eloquent-mclean-ss93m?file=/src/App.js + mountNode = getPopupContainer(domNode); + } if (mountNode) { mountNode.appendChild(popupContainer); From 3a9fe0e3d11187f2dd0fe5f57a45b22dc91b7cb1 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 25 Sep 2020 13:49:18 +0800 Subject: [PATCH 2/4] test: check for nodes test --- examples/case.tsx | 5 ++++ src/index.tsx | 11 ++++++--- tests/basic.test.jsx | 57 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/examples/case.tsx b/examples/case.tsx index 8c2f0066..b0c0b83a 100644 --- a/examples/case.tsx +++ b/examples/case.tsx @@ -196,6 +196,11 @@ const Demo = () => { adjustY: 1, }, }} + popupVisible + getPopupContainer={node => { + console.log('G<>>>>>>', node); + return node.parentElement; + }} popupPlacement={placement} destroyPopupOnHide={destroyPopupOnHide} mask={mask} diff --git a/src/index.tsx b/src/index.tsx index baaa732e..c29bffed 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -146,6 +146,8 @@ export function generateTrigger( triggerRef = React.createRef(); + attachId?: number; + clickOutsideHandler: CommonEventHandler; touchOutsideHandler: CommonEventHandler; @@ -540,14 +542,17 @@ export function generateTrigger( }; attachParent = (popupContainer: HTMLDivElement) => { + raf.cancel(this.attachId); + const { getPopupContainer, getDocument } = this.props; const domNode = this.getRootDomNode(); let mountNode: HTMLElement; if (!getPopupContainer) { mountNode = getDocument().body; - } else if (domNode) { - // Compatible for sync render usage + } else if (domNode || getPopupContainer.length === 0) { + // Compatible for legacy getPopupContainer with domNode argument. + // If no need `domNode` argument, will call directly. // https://codesandbox.io/s/eloquent-mclean-ss93m?file=/src/App.js mountNode = getPopupContainer(domNode); } @@ -556,7 +561,7 @@ export function generateTrigger( mountNode.appendChild(popupContainer); } else { // Retry after frame render in case parent not ready - raf(() => { + this.attachId = raf(() => { this.attachParent(popupContainer); }); } diff --git a/tests/basic.test.jsx b/tests/basic.test.jsx index bf51275a..baecc375 100644 --- a/tests/basic.test.jsx +++ b/tests/basic.test.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; import Portal from 'rc-util/lib/Portal'; import Trigger from '../src'; @@ -683,4 +684,60 @@ describe('Trigger.Basic', () => { expect(popupDomNode.style.color).toBe(style.color); expect(popupDomNode.style.top).toBe(`${style.top}px`); }); + + describe('getContainer', () => { + it('not trigger when dom not ready', () => { + const getPopupContainer = jest.fn(node => node.parentElement); + + function Demo() { + return ( + tooltip2} + > +
click
+
+ ); + } + + const wrapper = mount(); + + expect(getPopupContainer).toHaveReturnedTimes(0); + + act(() => { + jest.runAllTimers(); + }); + expect(getPopupContainer).toHaveReturnedTimes(1); + expect(getPopupContainer).toHaveBeenCalledWith( + wrapper.find('.target').instance(), + ); + }); + + it('not trigger when dom no need', () => { + let triggerTimes = 0; + const getPopupContainer = () => { + triggerTimes += 1; + return document.body; + }; + + function Demo() { + return ( + tooltip2} + > +
click
+
+ ); + } + + const wrapper = mount(); + + expect(triggerTimes).toEqual(1); + + wrapper.unmount(); + }); + }); }); From 20de1a7e1b487d8174fb9b7e4e6b76cd71ede550 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 25 Sep 2020 14:04:25 +0800 Subject: [PATCH 3/4] update deps --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc340cdf..c816eaf5 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,6 @@ "classnames": "^2.2.6", "rc-align": "^4.0.0", "rc-motion": "^2.0.0", - "rc-util": "^5.2.1" + "rc-util": "^5.3.4" } } From da1c724ec0f5cb14db14bc27488bde3d29847516 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 25 Sep 2020 14:14:07 +0800 Subject: [PATCH 4/4] clean up --- examples/case.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/case.tsx b/examples/case.tsx index b0c0b83a..8c2f0066 100644 --- a/examples/case.tsx +++ b/examples/case.tsx @@ -196,11 +196,6 @@ const Demo = () => { adjustY: 1, }, }} - popupVisible - getPopupContainer={node => { - console.log('G<>>>>>>', node); - return node.parentElement; - }} popupPlacement={placement} destroyPopupOnHide={destroyPopupOnHide} mask={mask}