software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
8.59k stars 1.26k forks source link

use hook useFrameCallback error #6158

Closed jameheller98 closed 6 days ago

jameheller98 commented 6 days ago

Description

I test useFrameCallback and its not work, after I check hook useFrameCallback in library, and I fix code and its work, i dont know how to useRef work to object and you can check code me about problem.

'use strict';
import { useEffect, useRef } from 'react';
import FrameCallbackRegistryJS from '../frameCallback/FrameCallbackRegistryJS';
import type { FrameInfo } from '../frameCallback/FrameCallbackRegistryUI';

export type FrameCallback = {
  setActive: (isActive: boolean) => void;
  isActive: boolean;
}; // Remove type callbackId

const frameCallbackRegistry = new FrameCallbackRegistryJS();

export function useFrameCallback(
  callback: (frameInfo: FrameInfo) => void,
  autostart = true
): FrameCallback {
  const refCallbackId = useRef(-1)
  const ref = useRef<FrameCallback>({
    setActive: (isActive: boolean) => {
      frameCallbackRegistry.manageStateFrameCallback(
        refCallbackId.current, //change callbackId
        isActive
      );
      ref.current.isActive = isActive;
    },
    isActive: autostart,
  }); //Remove prop callbackId

  useEffect(() => {
    refCallbackId.current =
      frameCallbackRegistry.registerFrameCallback(callback); //change callbackId
    const memoizedId = refCallbackId.current; //change callbackId
    ref.current.setActive(ref.current.isActive);

    return () => {
      frameCallbackRegistry.unregisterFrameCallback(memoizedId);
    };
  }, [callback, autostart]);

  return {...ref.current, callbackId: refCallbackId.current}; //change callbackId
}

Steps to reproduce

useFrameCallback in project

Snack or a link to a repository

https://snack.expo.dev/@jameheller98/useframecallback

Reanimated version

^3.12.0

React Native version

0.71.7

Platforms

Android

JavaScript runtime

Hermes

Workflow

React Native

Architecture

Paper (Old Architecture)

Build type

Debug app & dev bundle

Device

Android emulator

Device model

Google pixel 6

Acknowledgements

Yes

szydlovsky commented 6 days ago

Hey @jameheller98 I have so many questions. Could you tell us what exactly is the problem? When i tried using your code that you provided, all of our examples using useFrameCallback stopped working as intended because of your callbackId logic. What exactly do you want us to do?

szydlovsky commented 6 days ago

Funfact: if you change autostart argument in the snack to true (or just remove it), it will work fine

jameheller98 commented 6 days ago

This here video example about error:

Uploading screen-20240624-204905~2.mp4…

I have found error when ref.current.callbackId not update in useEffect hook you can check.

szydlovsky commented 6 days ago

@jameheller98 there is no video 😄

jameheller98 commented 6 days ago

@szydlovsky

https://github.com/software-mansion/react-native-reanimated/assets/32564261/e6bb2c6f-cd3b-49a6-8e3b-182592271d34

You can check again.

useFrameCallback.zip

And file fix you can check

szydlovsky commented 6 days ago

@jameheller98 alright, I can see there is some kind of error but I can't really go into detail and investigate without any reproduction. Please refer to how to make a minimal repro.

Your file fix unfortunately doesn't do the job - it breaks the logic of callbackId (stopping and activating callbacks doesn't work anymore because of wrong callbackId).

Other than that, I am also a bit puzzled that your fix contains changes to the code that weren't there yet as of 3.12 (they are present only on main branch and a few recent nightly builds).

jameheller98 commented 6 days ago

Okay I have found problem, its terrible with my code and thank to issue https://github.com/software-mansion/react-native-reanimated/issues/5525, I fix my code I had use runOnJS(frameCb.setActive)(true) in a worklet and that terrible, thank support to me @szydlovsky