pmndrs / react-spring

✌️ A spring physics based React animation library
http://www.react-spring.dev/
MIT License
28.2k stars 1.19k forks source link

[bug]: useSpring not working with ternary condition? #2316

Closed AnesBkdm closed 3 weeks ago

AnesBkdm commented 2 months ago

Which react-spring target are you using?

What version of react-spring are you using?

9.7.4

What's Wrong?

Changing the state does not change the ternary condition inside useSpring. However, the value initially rendered is correct.

To Reproduce

Used packages (package.json):

"dependencies": {
    "@react-spring/three": "^9.7.4",
    "@react-three/drei": "^9.112.0",
    "@react-three/fiber": "^8.17.6",
    "expo": "~51.0.28",
    "expo-font": "~12.0.10",
    "expo-gl": "~14.0.2",
    "expo-linear-gradient": "~13.0.2",
    "expo-status-bar": "~1.12.1",
    "expo-three": "^8.0.0",
    "prop-types": "^15.8.1",
    "r3f-native-orbitcontrols": "^1.0.12",
    "react": "18.2.0",
    "react-native": "0.74.5",
    "three": "^0.168.0"
  },

Code to reproduce:

function RecordScene({
    frontArtworkUrl,
    backArtworkUrl,
    boxColor,
    recordColor,
    recordDecorColor,
    idleRecordRotateSpeed,
    texture,
}) {
    // Refs
    const recordGroupRef = useRef();
    const recordBoxGroupRef = useRef();
    const recordVinylGroupRef = useRef();

    const { setFrameloop } = useThree();
    const { nodes } = useGLTF(Model);

    // Record and Box position
    const [ opened, setOpened ] = useState(false);

    // Animation
    const { z: recordZ } = useSpring({
        z: opened ? 0: -.225,
    });

    const { z: boxZ } = useSpring({
        z: opened ? 0: .225,
    });

    // Textures
    const {
        frontCoverTexture,
        backCoverTexture,
        coverNormalTexture,
        coverRoughnessTexture,
    } = useLoadCoverTextures(texture, frontArtworkUrl, backArtworkUrl);

    const { vinylNormalTexture, vinylRoughnessTexture } = useLoadVinylTextures(texture);

    useEffect(() => {
        setFrameloop("always");
    }, []);

    useFrame((_, delta) => {
        recordGroupRef.current.rotation.y += delta * idleRecordRotateSpeed;
    });

    useEffect(()=>{
        console.log(boxZ);
    },[boxZ]);

    useEffect(()=>{
        console.log(recordZ);
    },[recordZ]);

    return (
        <animated.group ref={recordGroupRef} dispose={null} scale={INITIAL_SCALE} rotation={INITIAL_ROTATION} onClick={()=>{setOpened(!opened)}}>
        <ambientLight intensity={2} />
        <directionalLight position={[-5, 3, 0]} castShadow intensity={1.25} />
        <directionalLight position={[-5, -3, 0]} castShadow intensity={1.25} />

            <animated.group ref={recordBoxGroupRef} castShadow position-z={boxZ}>
                <mesh geometry={nodes[RECORD_MODEL_NODES.box.frontCover].geometry} scale={RECORD_FRONT_COVER_INVERT_HORIZONTAL_SCALE}>
                    <meshStandardMaterial
                        attach="material"
                        map={frontCoverTexture}
                        normalMap={coverNormalTexture}
                        roughnessMap={coverRoughnessTexture}
                    />
                </mesh>
                <mesh geometry={nodes[RECORD_MODEL_NODES.box.backCover].geometry} scale={RECORD_FRONT_COVER_INVERT_HORIZONTAL_SCALE}>
                    <meshStandardMaterial
                        attach="material"
                        map={backCoverTexture}
                        normalMap={coverNormalTexture}
                        roughnessMap={coverRoughnessTexture}
                    />
                </mesh>
                <mesh geometry={nodes[RECORD_MODEL_NODES.box.body].geometry} material={new THREE.MeshStandardMaterial({ color: boxColor })} />
            </animated.group>
            <animated.group ref={recordVinylGroupRef} rotation={INITIAL_VINYL_ROTATION} position-z={recordZ} position-y={0.01}>
                <mesh geometry={nodes[RECORD_MODEL_NODES.vinyl.body].geometry}>
                    <meshStandardMaterial
                        attach="material"
                        color={recordColor}
                        normalMap={vinylNormalTexture}
                        roughnessMap={vinylRoughnessTexture}
                    />
                </mesh>
                <mesh geometry={nodes[RECORD_MODEL_NODES.vinyl.decor].geometry} material={new THREE.MeshStandardMaterial({ color: recordDecorColor })} />
                <mesh geometry={nodes[RECORD_MODEL_NODES.vinyl.center].geometry} material={new THREE.MeshStandardMaterial({ color: recordDecorColor })} />
            </animated.group>
        </animated.group>
    );
}

useGLTF.preload(Model);

Expected Behaviour

const { z: recordZ } = useSpring({
        z: opened ? 0: -.225,
});

This should change the recordZ value.

Writing a console.log(recordZ) and console.log(opened) shows that the value does not move whatsoever even when the opened state changes.

Link to repo

-

AnesBkdm commented 1 month ago

Update: the exact same code (minus the obvious View <-> div adaptations) work on Desktop (Nextjs). Still no idea why it fails on Expo. Any idea?

joshuaellis commented 3 weeks ago

Closing, your repo is too complicated, probably require a stackblitz to meaningfully look into this.