From 80d9d7cc31f3ee99da6af0e66fa608cfa60ad703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Chaves=20Neto?= Date: Mon, 20 Jan 2020 19:40:20 -0300 Subject: [PATCH] [Tooltip] Fix popper.js re-instantiation (#19304) --- packages/material-ui/src/Tooltip/Tooltip.js | 22 ++++++++++++------- .../material-ui/src/Tooltip/Tooltip.test.js | 18 ++++++++++++++- test/utils/createClientRender.js | 9 ++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/packages/material-ui/src/Tooltip/Tooltip.js b/packages/material-ui/src/Tooltip/Tooltip.js index 9a84a34632c91e..ff299f448a9a05 100644 --- a/packages/material-ui/src/Tooltip/Tooltip.js +++ b/packages/material-ui/src/Tooltip/Tooltip.js @@ -482,6 +482,19 @@ const Tooltip = React.forwardRef(function Tooltip(props, ref) { } } + // Avoid the creation of a new Popper.js instance at each render. + const popperOptions = React.useMemo( + () => ({ + modifiers: { + arrow: { + enabled: Boolean(arrowRef), + element: arrowRef, + }, + }, + }), + [arrowRef], + ); + return ( {React.cloneElement(children, { ref: handleRef, ...childrenProps })} @@ -495,14 +508,7 @@ const Tooltip = React.forwardRef(function Tooltip(props, ref) { open={childNode ? open : false} id={childrenProps['aria-describedby']} transition - popperOptions={{ - modifiers: { - arrow: { - enabled: Boolean(arrowRef), - element: arrowRef, - }, - }, - }} + popperOptions={popperOptions} {...interactiveWrapperListeners} {...PopperProps} > diff --git a/packages/material-ui/src/Tooltip/Tooltip.test.js b/packages/material-ui/src/Tooltip/Tooltip.test.js index 502b22568ea946..ee89abcbd5aaf6 100644 --- a/packages/material-ui/src/Tooltip/Tooltip.test.js +++ b/packages/material-ui/src/Tooltip/Tooltip.test.js @@ -220,10 +220,10 @@ describe('', () => { it('should use hysteresis with the enterDelay', () => { const { container } = render( , ); const children = container.querySelector('#testChild'); @@ -466,4 +466,20 @@ describe('', () => { ); }); }); + + it('should use the same popper.js instance between two renders', () => { + const popperRef = React.createRef(); + const { forceUpdate } = render( + , + ); + const firstPopperInstance = popperRef.current; + forceUpdate(); + expect(firstPopperInstance).to.equal(popperRef.current); + }); }); diff --git a/test/utils/createClientRender.js b/test/utils/createClientRender.js index 945c6df035b993..1bc67bab9647ee 100644 --- a/test/utils/createClientRender.js +++ b/test/utils/createClientRender.js @@ -63,6 +63,15 @@ function clientRender(element, options = {}) { return result; }; + result.forceUpdate = function forceUpdate() { + result.rerender( + React.cloneElement(element, { + 'data-force-update': String(Math.random()), + }), + ); + return result; + }; + return result; }