UNPKG

expo-modules-core

Version:
54 lines (44 loc) 1.75 kB
'use client'; import { DependencyList, useRef, useMemo, useEffect } from 'react'; import type { SharedObject } from '../ts-declarations/SharedObject'; /** * Returns a shared object, which is automatically cleaned up when the component is unmounted. */ export function useReleasingSharedObject<TSharedObject extends SharedObject>( factory: () => TSharedObject, dependencies: DependencyList ): TSharedObject { const objectRef = useRef<TSharedObject | null>(null); const isFastRefresh = useRef(false); const previousDependencies = useRef<DependencyList>(dependencies); if (objectRef.current == null) { objectRef.current = factory(); } const object = useMemo(() => { let newObject = objectRef.current; const dependenciesAreEqual = previousDependencies.current?.length === dependencies.length && dependencies.every((value, index) => value === previousDependencies.current[index]); // If the dependencies have changed, release the previous object and create a new one, otherwise this has been called // because of a fast refresh, and we don't want to release the object. if (!newObject || !dependenciesAreEqual) { objectRef.current?.release(); newObject = factory(); objectRef.current = newObject; previousDependencies.current = dependencies; } else { isFastRefresh.current = true; } return newObject; }, dependencies); useEffect(() => { isFastRefresh.current = false; return () => { // This will be called on every fast refresh and on unmount, but we only want to release the object on unmount. if (!isFastRefresh.current && objectRef.current) { objectRef.current.release(); } }; }, []); return object; }