Im using React Navigation's useNavigation hook:
In MyComponent.js:
import { useNavigation } from "@react-navigation/native";
const MyComponent = () => {
    const navigation = useNavigation();
    const handleNav = () => {
        navigation.navigate("about");
    };
    return(
        <TouchableOpacity onPress={handleNav}>
            <Text>About</Text>
        </TouchableOpacity>
    )
}
Is there a way to move this functionality to a custom hook? I tried the following:
In useCustomNav.js:
import { useNavigation } from "@react-navigation/native";
const useCustomNav = ({ to }) => {
  const navigation = useNavigation();
  navigation.navigate(to);
  return null;
};
export default useCustomNav;
In MyComponent.js:
import useCustomNav from './useCustomNav';
const MyComponent = () => {
    const handleNav = () => {
        useCustomNav("about");
    };
    return(
        <TouchableOpacity onPress={handleNav}>
            <Text>About</Text>
        </TouchableOpacity>
    )
}
Im getting an error:
Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component.
I understand that this is happening as useNavigation is 'hidden' within a function call but not how to fix it.
The reason Im trying to do this is I'm sharing code between a React Native and React Native Web project but I need to do routing differently. Expo can target different platforms with different file names eg useCustomNav.native.js for native and useCustomNav.web.js for the web. So I need to have a swappable function for routing for the different platforms. I cant have the useNavigation hook in MyComponent as it's only going to be used for native, it will error for web.
You can return a function from the custom navigator hook to let you navigate to the route that you want.
const useCustomNav = () => {
  const navigation = useNavigation();
  const goTo = to => navigation.navigate(to);
  return {goTo};
};
And use it like:
const MyComponent = () => {
    const navigator = useCustomNav();
    const handleNav = () => {
        navigator.goTo("about");
    };
    return(
        <TouchableOpacity onPress={handleNav}>
            <Text>About</Text>
        </TouchableOpacity>
    )
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With