Reputation: 23593
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.
Upvotes: 4
Views: 5992
Reputation: 141
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>
)
}
Upvotes: 7