Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native's useNavigation hook inside of a custom hook?

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.

like image 750
Evanss Avatar asked Sep 16 '25 06:09

Evanss


1 Answers

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>
    )
}
like image 137
Ravi Avatar answered Sep 17 '25 22:09

Ravi