Files
react-navigation/packages/core/src/useIsFocused.tsx
Satyajit Sahoo 66f3a4a0bb fix: don't use use-subscription to avoid peer dep related errors
The `use-subscription` package has a peer dep on latest React. This is problematic when using npm due to it's peer dependency algorithm which installs multiple versions of React when using an older version of React (Native).

This means that we'll need to use an ancient version of `use-subscription` to support older React versions with npm and make sure to never update it, or test with every version.

It's much lower maintenance to incporporate the same update in render logic that `use-subscription` has and not deal with dependencies. So this commit removes the `use-subscription` dependency.

See https://github.com/react-navigation/react-navigation/issues/9021#issuecomment-721679760 for more context.
2020-11-04 13:06:49 +01:00

43 lines
1.4 KiB
TypeScript

import * as React from 'react';
import { useState } from 'react';
import useNavigation from './useNavigation';
/**
* Hook to get the current focus state of the screen. Returns a `true` if screen is focused, otherwise `false`.
* This can be used if a component needs to render something based on the focus state.
*/
export default function useIsFocused(): boolean {
const navigation = useNavigation();
const [isFocused, setIsFocused] = useState(navigation.isFocused);
const valueToReturn = navigation.isFocused();
if (isFocused !== valueToReturn) {
// If the value has changed since the last render, we need to update it.
// This could happen if we missed an update from the event listeners during re-render.
// React will process this update immediately, so the old subscription value won't be committed.
// It is still nice to avoid returning a mismatched value though, so let's override the return value.
// This is the same logic as in https://github.com/facebook/react/tree/master/packages/use-subscription
setIsFocused(valueToReturn);
}
React.useEffect(() => {
const unsubscribeFocus = navigation.addListener('focus', () =>
setIsFocused(true)
);
const unsubscribeBlur = navigation.addListener('blur', () =>
setIsFocused(false)
);
return () => {
unsubscribeFocus();
unsubscribeBlur();
};
}, [navigation]);
React.useDebugValue(valueToReturn);
return valueToReturn;
}