Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popover/Tooltip breaks if parent is smaller(height) causing memory leak. #1482

Closed
rabrenio opened this issue May 6, 2019 · 14 comments · Fixed by #1669 · May be fixed by largerock/largerock.com#5
Closed

Popover/Tooltip breaks if parent is smaller(height) causing memory leak. #1482

rabrenio opened this issue May 6, 2019 · 14 comments · Fixed by #1669 · May be fixed by largerock/largerock.com#5

Comments

@rabrenio
Copy link

rabrenio commented May 6, 2019

  • components: Popover/Tooltip
  • reactstrap version 8.0.0

Here is how you can replicate the issue.

Tooltip's works if you set placement.

This can also happens if the window size is smaller than the Popover/Tooltip.

codesanbox

@rabrenio rabrenio changed the title Popover/Tooltip breaks if parent is smaller(height) Popover/Tooltip breaks if parent is smaller(height) causing memory leak. May 6, 2019
@jisaf
Copy link

jisaf commented May 13, 2019

I will add to this - we're running into this problem as well.

After updating to 8.0.0 one of our tooltips (specifically, one used on an AgGrid row) is causing the CPU to jump to 100% and lock up the browser.

Reverting to pre-8 solves the problem (for anyone reading this, note that whatever dev-server you're running will probably need to be re-started as well).

Increasing the height of the row, however, does not seem to solve the problem.

@leocorder
Copy link

Same problem here after update from 6.5.0 to 8.0.0.

@val1984
Copy link

val1984 commented May 23, 2019

Getting this issue too when using reactstrap@8.0.0.
Seems that the browser is locked in an async deadlock.

@YassienW
Copy link

YassienW commented Jun 4, 2019

Same thing here, does anyone have any pointers as to what specifically is causing this? Or to any possible workarounds?

@leocorder
Copy link

@YassienW I ended up rolling back to version 6.5.0.

@choweiyuan
Copy link

Same thing here, does anyone have any pointers as to what specifically is causing this? Or to any possible workarounds?

@YassienW #1488 (comment) try setting placement as suggested from the linked comment

@YassienW
Copy link

YassienW commented Jun 4, 2019

It does fix it since it stops the infinite render loop. I am not sure whether this is an issue with reactstrap or react-popper though.

@val1984
Copy link

val1984 commented Jun 4, 2019

Considering #1488 (comment) fixes this issue, it seems that what happens is that this.state.placement keeps flip-flopping when there's not enough space, resulting in a deadlock since ReactPopper return a different placement each time than the original one which cannot be honored.

@val1984
Copy link

val1984 commented Jun 4, 2019

A fix which doesn't require modifying reactstrap, until it is fixed, is to add the following modifiers prop to your Popover or Tooltip:

<Popover placement="bottom"
  modifiers={{ flip: { behavior: ['bottom'] } }}
  // additional props
>
  // children
</Popover>

placement and modifiers.flip.behavior need to have the same value for it to work.

@YassienW
Copy link

YassienW commented Jun 4, 2019

My scenario was a little different (Edit: Not really), the popover was within a <ListGroup/> with overflow-y: auto. Poppers are restricted to the boundaries of their scroll parents by default (the <ListGroup/> in this case), which means that whenever the list was too small, it triggered this memory leak because there was no space. The fix for this was to change poppers' settings (modifiers) on the <Popover/> to restrict the popper to the viewport instead of the scroll parent, which gave it more space and stopped this memory leak.

<Popover modifiers={{preventOverflow: {boundariesElement: "viewport"}}}>

As per popper's documentation you can set this boundary to any DOM element as well, as long as the popper has enough space to render it shouldn't trigger the crash.

Obviously this doesn't fix the root problem, but for anyone with the same scenario, this is the best fix yet.

@rabrenio
Copy link
Author

rabrenio commented Jun 7, 2019

Another temporary fix is to disable the flip property which is true by default.

@mrudowski
Copy link

in my case (placement: "bottom") the code below fix this and save the basic flip functionality (it will flip but not turn to its original position)

modifiers={{
flip: {
  enable: true,
  behavior: ['bottom', 'top', 'bottom']
}
}}

@gthomas-appfolio
Copy link
Contributor

This is a pretty nasty issue, anyone looked at or pointers on how we can PR in v8 aside from the workarounds?

@blanet
Copy link

blanet commented Sep 10, 2019

I avoid this by setting the Popover size explicitly, it's not a perfect solution but it does work in some cases when flipping is necessary and the popover size can be fixed.

...
style={{
    width: '270px',
    height: '200px',
 }}
...

phwebi added a commit to phwebi/reactstrap that referenced this issue Oct 17, 2019
…ining element

When a tooltip or popover does not fit in the containing element, this causes the `PopperContent` component to get into an infinite loop of switching between `placement`s in its state. This is because we attempt to update `this.state.placement` everytime popper.js flips the placement to find a better fit and pass it back as the `placement` property to `ReactPopper`.

This is a problem because the `PopperContent` component has two sources of truth for its placement. One coming from its own `placement` property, and one coming from the internal data of `ReactPopper`.

This commit fixes the issue by using `PopperContent`'s `placement` property as the initial placement of the `ReactPopper` component and allowing `ReactPopper` to manage its own updates (i.e. if the popover needs to be flipped because there's not enough room for the specified placement.)

Fixes reactstrap#1482
Fixes reactstrap#1488
@phwebi phwebi mentioned this issue Oct 17, 2019
12 tasks
TheSharpieOne pushed a commit that referenced this issue Oct 18, 2019
When a tooltip or popover does not fit in the containing element, this causes the `PopperContent` component to get into an infinite loop of switching between `placement`s in its state. This is because we attempt to update `this.state.placement` everytime popper.js flips the placement to find a better fit and pass it back as the `placement` property to `ReactPopper`.

This is a problem because the `PopperContent` component has two sources of truth for its placement. One coming from its own `placement` property, and one coming from the internal data of `ReactPopper`.

This commit fixes the issue by using `PopperContent`'s `placement` property as the initial placement of the `ReactPopper` component and allowing `ReactPopper` to manage its own updates (i.e. if the popover needs to be flipped because there's not enough room for the specified placement.)

Fixes #1482
Fixes #1488
Fixes #1664
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment