UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

89 lines (85 loc) 3.12 kB
'use strict'; import { useRef, useState } from 'react'; import { makeShareableCloneRecursive, shareableMappingCache } from 'react-native-worklets'; import { SHOULD_BE_USE_WEB } from "../common/constants.js"; import { getShadowNodeWrapperFromRef } from '../fabricUtils'; import { makeMutable } from "../mutables.js"; import { findNodeHandle } from '../platformFunctions/findNodeHandle'; function getComponentOrScrollable(component) { if (component.getNativeScrollRef) { return component.getNativeScrollRef(); } if (component.getScrollableNode) { return component.getScrollableNode(); } return component; } function useAnimatedRefBase(getWrapper) { const observers = useRef(new Map()).current; const wrapperRef = useRef(null); const ref = useRef(null); if (!ref.current) { const fun = component => { if (component) { wrapperRef.current = getWrapper(component); // We have to unwrap the tag from the shadow node wrapper. fun.getTag = () => findNodeHandle(getComponentOrScrollable(component)); fun.current = component; if (observers.size) { const currentTag = fun?.getTag?.() ?? null; observers.forEach((cleanup, observer) => { // Perform the cleanup before calling the observer again. // This ensures that all events that were set up in the observer // are cleaned up before the observer sets up new events during // the next call. cleanup?.(); observers.set(observer, observer(currentTag)); }); } } return wrapperRef.current; }; fun.observe = observer => { // Call observer immediately to get the initial value const cleanup = observer(fun?.getTag?.() ?? null); observers.set(observer, cleanup); return () => { observers.get(observer)?.(); observers.delete(observer); }; }; fun.current = null; ref.current = fun; } return ref.current; } function useAnimatedRefNative() { const [sharedWrapper] = useState(() => makeMutable(null)); const ref = useAnimatedRefBase(component => { const currentWrapper = getShadowNodeWrapperFromRef(getComponentOrScrollable(component)); sharedWrapper.value = currentWrapper; return currentWrapper; }); if (!shareableMappingCache.get(ref)) { const animatedRefShareableHandle = makeShareableCloneRecursive({ __init: () => { 'worklet'; return () => sharedWrapper.value; } }); shareableMappingCache.set(ref, animatedRefShareableHandle); } return ref; } function useAnimatedRefWeb() { return useAnimatedRefBase(component => getComponentOrScrollable(component)); } /** * Lets you get a reference of a view that you can use inside a worklet. * * @returns An object with a `.current` property which contains an instance of a * component. * @see https://docs.swmansion.com/react-native-reanimated/docs/core/useAnimatedRef */ export const useAnimatedRef = SHOULD_BE_USE_WEB ? useAnimatedRefWeb : useAnimatedRefNative; //# sourceMappingURL=useAnimatedRef.js.map