gilbarbara / react-joyride

Create guided tours in your apps
https://react-joyride.com/
MIT License
6.64k stars 519 forks source link

overlay flickering when switching steps caused by async state updates and react strict mode #914

Closed dumimerlusca closed 1 year ago

dumimerlusca commented 1 year ago

šŸ› Bug Report

Hi, I noticed that the overlay component is causing some flickering, it is wrongly unmounted and the quickly mounted again when switching between steps in those 2 cases:

  1. The app is wrapped inside React.StrictMode
  2. If state updates are triggered in an async way, for ex: calling the next function from a setTimeout.

I encountered some situations where I commonly need to use timeouts for changing the state, like opening/closing dropdowns/modals before allowing the user to proceed to further steps. Having that flickering just looks bad.

Not sure exactly what is causing this but changing some lifecycle condition for unmounting the Overlay component seems to work .

sandbox : https://codesandbox.io/s/react-joyride-overlay-flickering-bug-hkr83n

gilbarbara commented 1 year ago

Hey @dumimerlusca

Yes, the StrictMode mounts the component twice, causing the flickering. However, this only happens in development.

Removing the StrictMode in the sandbox didn't cause any flickering with the delayed next calls, though.

Not sure exactly what is causing this but changing some lifecycle condition for unmounting the Overlay component seems to work .

What do you mean? Changing the lifecycle calls inside the library?

dumimerlusca commented 1 year ago

@gilbarbara Thanks for answering

Can you please check again the delayed next call? I'm definitely seeing the flickering

I'm talking about this condition if (disableOverlay || lifecycle !== LIFECYCLE.TOOLTIP) { return null; } any time the step is changed the overlay is removed from the dom based on the lifecycle condition and added back when the new step reaches tooltip lifecycle, yet it is only noticeable in the delayed state update case

gilbarbara commented 1 year ago

I can see the overlay flickering with the delayed transition sometimes, but not consistently. But it doesn't happen without the timeout, so it's not directly related to the conditional you mentioned.

Have you tried using the controlled mode? That might fix it. Check the Controlled example in the codesanbox demo.

dumimerlusca commented 1 year ago

I can see the exact same issue in that demo, but it's not considered to be an issue i guess, the fact that the overlay is rendered individually again by each step and any time there is some delay between steps the fact that the overlay was removed and added again is noticeable. It doesn't seem a smooth transition to me.

I'll go around this by disabling the default overlay and creating a custom one if you don't consider this an issue.

Also, If I may do a suggest for a future library improvement, I really don't like the callback approach for performing "in between steps" logic, that function can get messy and too big really quickly, so what I ended up doing in my project is adding some additional middleware methods to each step ( with a custom tooltip component ) onNextMIddleware(e, next) onPrevMIddleware(e, next) onMountMiddleware(e, next) ...

@gilbarbara Many thanks!

juniorforlife commented 8 months ago

@dumimerlusca Iā€™m having the same issue.How did you create the custom overlay?