react-spring: three and web are incompatible

🐛 Bug Report

react-spring/web is not working when a @react-spring/three happens before, unless both is happeing in the same file. From here on this is just wild guessing from my side why this happens.

I am using react spring for a web and a threejs context. Respectivly importing both with

import { animated, useTransition, config, useSpring } from "@react-spring/web";
// or
import { useSpring, animated, config } from "@react-spring/three";

To Reproduce

Import a animated three component and a animated web component. The useSpring web component stops working:

bug

Expected behavior

Importing react-spring/three and react-spring/web both enable working springs no matter if imported from different files.

Link to repro (highly encouraged)

Working animations: https://codesandbox.io/s/single-file-69el5?file=/src/App.js Non Working example: https://codesandbox.io/s/multi-file-11oph?file=/src/App.js

Environment

  • react-spring v9.2.3
  • react v17.0.2

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 9
  • Comments: 28 (5 by maintainers)

Commits related to this issue

Most upvoted comments

@xiaotianxt I checked out your example after coming across this problem myself. It looks like the following suggestion may apply to you too as you’re using drei (https://github.com/pmndrs/react-spring/issues/1889#issuecomment-1286828218)

@laffan Drop the dependency on spring, drei already depens on it (https://www.npmjs.com/package/@react-three/drei?activeTab=dependencies) and having multiple version causes this issue.

Thanks @skrat - For some reason I had tried that and it wasn’t working, but once I deleted node_modules and reinstalled it works great.

I still have the Cannot call the manual advancement of rafz whilst frameLoop is not set as demand issue, which can be reproduced here.

I also faced the situation that a react-spring animation outside of an r3f Canvas is not executing when a Canvas with frameloop=“never” prop is present. A way to trigger the spring animation and even to set a frame rate for the animation is to use the advance method of raf like this:

import { raf } from "@react-spring/shared";

 useEffect(() => {
    // Execute the animation (by advancing the frameloop) 30 times per second
    const interval = setInterval(() => {
      raf.advance();
    }, 1000 / 30);
    return () => clearInterval(interval);
  }, []);

So I updated to the latest packages and tried it out today. The issue remains while your workaround works well:

import { Globals } from "@react-spring/shared";

Globals.assign({
  frameLoop: "always",
});

If someone is looking for a copy-paste solution.

Can I suppress the warning from react-spring-rafz somehow? Cannot call the manual advancement of rafz whilst frameLoop is not set as demand is spamming my sonsole.

@marceloavf no, sorry. I haven’t checked for a solution tbh. A quick search led me to console-suppress. As this is just a single view in my app I don’t mind too much.

Hm this is probably from the global side effect of importing anything from the animated file of @react-spring/three.

For some context we make @react-three/fiber control the rendering loop for three animated components because then it also works in XR see #1518. So the workaround would be to do:

Globals.assign({
  frameLoop: 'always',
})

which would then mean that our rafz package which uses the native requestAnimationFrame is running the render loop removing the r3f need.

If you have an idea on how to resolve this i’d be more than happy to hear it and talk through it more!