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

useRive React component lifecycle related init issue #210

Open
glomotion opened this issue Sep 27, 2023 · 4 comments
Open

useRive React component lifecycle related init issue #210

glomotion opened this issue Sep 27, 2023 · 4 comments

Comments

@glomotion
Copy link

glomotion commented Sep 27, 2023

Hello there! 👋

We are using useRive from this library for animations within our DesignSystem, and have noticed a pretty critical React component lifecycle related bug with the useRive hook. 😭
I've produced a simple reproduction of this bug in the latest published version of useRive from @rive-app/[email protected]

https://stackblitz.com/edit/stackblitz-starters-tc2yg6?file=app%2Fpage.tsx

Essentially, when first revealed (mounted), the Rive animation inits and autoplays as expected. However, once it's unmounted and then re-mounted (in this case using a simple conditional render bool) - the rive animation fails to init and autoplay.

Here is a simple code snippet which demonstrates the issue:

...
const [show, setShow] = useState(false);
const { RiveComponent } = useRive({
  src: 'https://cdn.rive.app/animations/vehicles.riv',
  autoplay: true,
  layout: new Layout({
    fit: Fit.Cover,
    alignment: Alignment.Center,
  }),
});

return (
  <div>
    <button onClick={() => setShow((old) => !old)}>toggle</button>
    {show && <RiveComponent style={{ width: '500px', height: '500px' }} />} {/*<-- this only loads up and plays the very first time it's mounted. :( */}
  </div>
 );
...
@glomotion glomotion changed the title Conditionally rendered useRive react display bug React component lifecycle related init issue Sep 27, 2023
@glomotion glomotion changed the title React component lifecycle related init issue useRive React component lifecycle related init issue Sep 27, 2023
@glomotion
Copy link
Author

glomotion commented Sep 27, 2023

FWIW - I have tested out the bog standard <Rive /> React component and this does not suffer from the same issue. eg:

import Rive from '@rive-app/react-canvas';

<button onClick={() => setShow(old => !old)}>toggle</button>
      {show && (
        <Rive
          src="https://cdn.rive.app/animations/vehicles.riv"
          style={{ width: '400px', height: '400px' }}
        />
      )} {/* works as expected when toggling on and off */}

@zplata
Copy link
Contributor

zplata commented Sep 28, 2023

Hi @glomotion - thanks for reporting, and the repro. We'll take a look, as this is definitely not ideal in React dev! I suspect the issue might be here, where only when the canvas is mounted (aka, RiveComponent) is new Rive({}) actually called. When unmounted, we "cleanup" rive (which is a bunch of internal logic to delete cpp-created objects under the hood and stop the animation loop).

If it's feasible for you in the meantime until we give this another pass, as you saw in your second comment, wrapping your logic of using useRive in a wrapper component might do the trick temporarily, rather than using it with other React state that conditionally renders the <RiveComponent /> from useRive that would cause the above issues mentioned.

So:

// RiveWrapperComponent.jsx
const { RiveComponent } = useRive({
  src: 'https://cdn.rive.app/animations/vehicles.riv',
  autoplay: true,
  layout: new Layout({
    fit: Fit.Cover,
    alignment: Alignment.Center,
  }),
});

return (
  <RiveComponent style={{ width: '500px', height: '500px' }} />
 );
 // ParentComponent.jsx
 const [show, setShow] = useState(false);
 return (
  <div>
    <button onClick={() => setShow((old) => !old)}>toggle</button>
    {show && <RiveWrapperComponent />
  </div>
 );

Again, definitely recognize it's not ideal and might be a workaround for now! This also somewhat goes along with #107 too, which is also on the plate.

@glomotion
Copy link
Author

glomotion commented Sep 28, 2023

@zplata thanks for the suggested work around, did figure something like that might work.
We can perhaps suggest to our DS consumers to just wrap their rive instances inside components for now.

@glomotion
Copy link
Author

@zplata I wonder, is there any idea of rough timeline for when this kind of bug and #107 might be worked on? I'm mindful that #107 has already been open for more than a year. 😅

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