4

How do i trigger a useEffect based on a sharedValue from the Reanimated libary?

 const sharedValue = useSharedValue(0);
  useEffect(() => {
    console.log("exectue functions");
  }, [sharedValue.value]);

Is there a best practice for this. Or is there another way to trigger functions (sync and async) based on a change in a sharedValue.

dan_boy
  • 1,735
  • 4
  • 19
  • 50

2 Answers2

9

You can use:

  1. useAnimatedReaction;
  2. useDerivedValue;

Solution with useAnimatedReaction

const sharedValue = useSharedValue(0);

useAnimatedReaction(() => {
    return sharedValue.value;
  }, (result, previous) => {
    if (result !== previous) {
       console.log(result)
    }
 }, []); // No need to pass dependencies

Solution with useDerivedValue

const sharedValue = useSharedValue(0);

useDerivedValue(() => {
    console.log(sharedValue.value);
}, []); // No need to pass dependencies

0

useSharedValue in the Reanimated v2 library actually returns a reference and in react useEffect does not trigger on mutation in reference variable. So if you want to execute functions with changing useSharedValue I suggest you use useCallback or a function trigger.

EDIT:

UseCallback would only work for node references such as

const Component = () => {
  const [isMounted, toggle] = useReducer((p) => !p, true);
  const [elementRect, setElementRect] = useState();

  const handleRect = useCallback((node) => {
    setElementRect(node?.getBoundingClientRect());
  }, []);

  return (
    <>
      {isMounted && <div ref={handleRect}>Example</div>}
      <button onClick={toggle}>Toggle</button>
      <pre>{JSON.stringify(elementRect, null, 2)}</pre>
    </>
  );
};

If you want to make one with sharedRef then functional trigger is your only option:

const Component = () => {

const shared = useSharedValue(0);
const _incShared = () => shared.value++;

return(
<View></View>
)
}
Vin Xi
  • 986
  • 2
  • 11