mirror of
https://github.com/zoriya/react-native-video.git
synced 2026-02-21 04:35:30 +00:00
75 lines
2.6 KiB
JavaScript
75 lines
2.6 KiB
JavaScript
"use strict";
|
|
|
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
|
|
/**
|
|
* @internal
|
|
* A hook that helps to manage the lifecycle of a native instance in a React component.
|
|
* It allows instance to be recreated when dependencies change, but not when the component is hot reloaded.
|
|
*
|
|
* @param config.factory - The factory function that creates the instance.
|
|
* @param config.cleanup - The cleanup function that destroys the instance.
|
|
* @param config.dependenciesEqualFn - The function that compares the dependencies.
|
|
*
|
|
* @param dependencies - The dependencies array.
|
|
* @returns The managed instance.
|
|
*/
|
|
export const useManagedInstance = (config, dependencies) => {
|
|
const {
|
|
factory,
|
|
cleanup,
|
|
dependenciesEqualFn
|
|
} = config;
|
|
const objectRef = useRef(null);
|
|
const isFastRefresh = useRef(false);
|
|
const previousDependencies = useRef(dependencies);
|
|
|
|
// Wee need to force a "re-render" to recalculate the object
|
|
const [released, setReleased] = useState(false);
|
|
if (objectRef.current == null) {
|
|
objectRef.current = factory();
|
|
}
|
|
const object = useMemo(() => {
|
|
let newObject = objectRef.current;
|
|
const dependenciesChanged = previousDependencies.current?.length === dependencies.length && dependencies.every((value, index) => dependenciesEqualFn?.(value, previousDependencies.current[index]) ?? value === previousDependencies.current[index]);
|
|
if (!newObject || !dependenciesChanged || released) {
|
|
// Destroy the old object
|
|
if (objectRef.current) {
|
|
cleanup(objectRef.current);
|
|
objectRef.current = null;
|
|
}
|
|
|
|
// Create a new object
|
|
newObject = factory();
|
|
objectRef.current = newObject;
|
|
setReleased(false);
|
|
|
|
// Update the previous dependencies
|
|
previousDependencies.current = dependencies;
|
|
} else {
|
|
// If useMemo is re-evaluated, but dependencies are the same
|
|
// and object is still the same, we can assume that that
|
|
// the component is being hot reloaded
|
|
isFastRefresh.current = true;
|
|
}
|
|
return newObject;
|
|
|
|
// factory and cleanup are stable, so we don't need to re-evaluate
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [...dependencies, released]);
|
|
useEffect(() => {
|
|
isFastRefresh.current = false;
|
|
return () => {
|
|
if (!isFastRefresh.current && objectRef.current) {
|
|
cleanup(objectRef.current);
|
|
objectRef.current = null;
|
|
setReleased(true);
|
|
}
|
|
};
|
|
|
|
// factory and cleanup are stable, so we don't need to re-evaluate
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
return object;
|
|
};
|
|
//# sourceMappingURL=useManagedInstance.js.map
|