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

Error since react-lottie-player 1.5.6 when used in mui Tooltip #125

Open
JannikGM opened this issue Apr 19, 2024 · 1 comment
Open

Error since react-lottie-player 1.5.6 when used in mui Tooltip #125

JannikGM opened this issue Apr 19, 2024 · 1 comment

Comments

@JannikGM
Copy link

JannikGM commented Apr 19, 2024

There was a subtle fix introduced in 7a4d36b:

Old code (1.5.5)

const setLottieRefs = useCallback((newRef) => {
animRef.current = newRef;
// eslint-disable-next-line no-param-reassign
if (forwardedRef) forwardedRef.current = newRef;
}, []); // eslint-disable-line react-hooks/exhaustive-deps

New code (1.5.6)

const setLottieRefs = useCallback((newRef) => {
animRef.current = newRef;
if (typeof forwardedRef === 'function') {
forwardedRef(newRef);
} else if (forwardedRef !== undefined && forwardedRef !== null) {
// eslint-disable-next-line no-param-reassign -- mutating a ref is intended
forwardedRef.current = newRef;
}
}, [forwardedRef]);

The old code was problematic because it uses ref.. sometimes.
The new code makes the ref handling better / more consistent, so it always returns a ref now.
Overall this is an improvement.


However, the new code triggers errors with mui Tooltips in a minor version upgrade.
(We use legacy material-ui 4.x, but the same problem still appears to apply to mui 5.x)

We have code like:

<Tooltip title="Tooltip text"...>
    <Lottie ... />
</Tooltip>

Our code was always broken because Tooltip expects the children to be DOM elements with ref.
This is documented here: https://mui.com/material-ui/api/tooltip/#props and here https://mui.com/material-ui/guides/composition/#caveat-with-refs
However, we didn't spot this issue.

This only started to cause errors (= webapp "crashes" in our case) in react-dom while running with vite devserver once we upgraded to 1.5.6:

Uncaught Error: Argument appears to not be a ReactComponent. Keys: _cbs,name,path,isLoaded,currentFrame,currentRawFrame,firstFrame,totalFrames,frameRate,frameMult,playSpeed,playDirection,playCount,animationData,assets,isPaused,autoplay,loop,renderer,animationID,assetsPath,timeCompleted,segmentPos,isSubframeEnabled,segments,_idle,_completedLoop,projectInterface,imagePreloader,audioController,markers,configAnimation,onSetupError,onSegmentComplete,drawnFrameEvent,expressionsPlugin,wrapper,animType,autoloadSegments,initialSegment,frameModifier

The error happens because Tooltip internally uses useForkRef to get the children ref.
useForkRef creates a function as forwardedRef which was used incorrectly in 1.5.5, so mui didn't see the ref.
In 1.5.6 the function is suddenly used, but it passes a non-DOM element to the Tooltip through forwardedRef.
When Tooltip tries to render the lottie object through react-dom, we get the error above.


We fixed this by wrapping Lottie in a div in our codebase (which clearly had a bug because it didn't meet mui requirements by using a non-DOM element as a child).

Personally, I consider this an issue in mui (expecting ref to be a DOM element), but I think react-lottie-player could also avoid this issue by not using the generic ref name for a non-DOM element.
I think for v3.x the ref prop should be renamed to lottieRef to avoid mistaking it for a DOM ref in popular libraries like mui.
For the main ref (if it even exists) it probably makes more sense to return the DOM container in which the lottie animation plays.

Other than that, this issue is mostly meant as a heads up to other people running into the same error / crash.

Also, if anyone has a linter rule to check for this (mui expecting DOM ref as child, but child isn't a DOM ref) that'd be excellent.

@mifi
Copy link
Owner

mifi commented Apr 21, 2024

I think for v3.x the ref prop should be renamed to lottieRef to avoid mistaking it for a DOM ref in popular libraries like mui.

Right. that's a good idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants