react-navigation-shared-element
Version:
react-native-shared-element bindings for React Navigation
46 lines • 2.35 kB
JavaScript
import { NavigationContext, } from "@react-navigation/native";
import * as React from "react";
/**
* A variation of useFocusEvents that uses a custom emitter
* and emits events using useLayoutEffect instead of useEffect.
* This enables shared element to respond to focus events in
* a timely manner.
* https://github.com/react-navigation/react-navigation/blob/master/packages/core/src/useFocusEvents.tsx
*/
export function useSharedElementFocusEvents({ state, emitter, }) {
const navigation = React.useContext(NavigationContext);
const lastFocusedKeyRef = React.useRef();
const currentFocusedKey = state.routes[state.index].key;
// When the parent screen changes its focus state, we also need to change child's focus
// Coz the child screen can't be focused if the parent screen is out of focus
React.useLayoutEffect(() => navigation?.addListener("focus", () => {
lastFocusedKeyRef.current = currentFocusedKey;
emitter.emit("focus", currentFocusedKey);
}), [currentFocusedKey, emitter, navigation]);
React.useLayoutEffect(() => navigation?.addListener("blur", () => {
lastFocusedKeyRef.current = undefined;
emitter.emit("blur", currentFocusedKey);
}), [currentFocusedKey, emitter, navigation]);
React.useLayoutEffect(() => {
const lastFocusedKey = lastFocusedKeyRef.current;
lastFocusedKeyRef.current = currentFocusedKey;
// We wouldn't have `lastFocusedKey` on initial mount
// Fire focus event for the current route on mount if there's no parent navigator
if (lastFocusedKey === undefined && !navigation) {
emitter.emit("focus", currentFocusedKey);
}
// We should only emit events when the focused key changed and navigator is focused
// When navigator is not focused, screens inside shouldn't receive focused status either
if (lastFocusedKey === currentFocusedKey ||
!(navigation ? navigation.isFocused() : true)) {
return;
}
if (lastFocusedKey === undefined) {
// Only fire events after initial mount
return;
}
emitter.emit("blur", lastFocusedKey);
emitter.emit("focus", currentFocusedKey);
}, [currentFocusedKey, emitter, navigation]);
}
//# sourceMappingURL=SharedElementFocusEvents.js.map