Comments (18)
IMO useNavigation
should take the type of navigation prop as the generic instead of S
(?):
const navigation = useNavigation<NavigationStackProp>();
cc @slorber
from hooks.
I'm using:
"@react-navigation/native": "^5.5.1",
"@react-navigation/stack": "^5.5.1",
But in the blow code I see TypeScript missing type error:
const { navigate, push } = useNavigation();
I guess the written types are not complete.
from hooks.
I ended up using this:
const { goBack, popToTop } = useNavigation<any>();
Pretty sure there is a better way, like it's mentioned here https://reactnavigation.org/docs/typescript/#type-checking-screens, but it didn't work for me probably because I didn't use it right 🤔
from hooks.
how do you plan to solve this in v5?
In v5, useNavigation
accepts an optional type parameter:
const navigation = useNavigation<StackNavigationProp<RootParamList>>()
For me all those are different syntaxes to downcast to a stack navigation object
In this case the end result is same, but type casting and generics have very different semantics.
With type casting, you tell the compiler that the value is a certain type and it won't complain even if it's not (as long as the interface matches vaguely). Typecasting should be avoided unless necessary.
A generic is like a parameter, TypeScript will show type hints that the hook accepts this type parameter, it maybe required or optional, the hook can ensure that supplied type parameter matches the desired constraint.
Consider the following 2 snippets:
useNavigation() as { setParams: Function }; // No error
useNavigation<{ setParams: Function }>(); // Shows error since the supplied type doesn't match constraint
If you call
useStackNavigation
and it returns a switch navigation, that could be misleading as well. Maybe we should have a custom hook for each type of navigator to encapsulate the casting + a runtime assertion to ensure we don't return a switch navigator when user calluseStackNavigation
?
The problem here is that we grab the value automatically from the context. There's no way to statically verify that the type/function being used is correct so we need to entirely trust user on this.
A navigation object can be a combination of multiple navigation objects as well (e.g. have both push
and openDrawer
methods) depending on nesting, so we can't restrict the type to only one navigator either.
A runtime assertion will provide minimal value here imo, at the cost of each navigator needing to export their own hook.
from hooks.
useNavigation is never going to have the stack props on it. If you look at my canny feature request the maintainers explained why. You have to type cast to the StackNavigationProp if you want to "safely" use stack props.
from hooks.
yeah that's probably right, will try to see how to expose custom nav actions more easily
from hooks.
Edit: that was a suggestion? I thought that you said it could be used that way in the current version XD
@satya164 the return type of the hook is NavigationScreenProp<S & NavigationRoute>
and the type is defined as (in react-navigation package):
export interface NavigationScreenProp<S, P = NavigationParams> {
state: S & { params?: P };
dispatch: NavigationDispatch;
goBack: (routeKey?: string | null) => boolean;
dismiss: () => boolean;
navigate(options: {
routeName:
| string
| {
routeName: string;
params?: NavigationParams;
action?: NavigationNavigateAction;
key?: string;
};
params?: NavigationParams;
action?: NavigationAction;
key?: string;
}): boolean;
navigate(
routeNameOrOptions: string,
params?: NavigationParams,
action?: NavigationAction
): boolean;
openDrawer: () => any;
closeDrawer: () => any;
toggleDrawer: () => any;
getParam<T extends keyof P>(
param: T,
fallback: NonNullable<P[T]>
): NonNullable<P[T]>;
getParam<T extends keyof P>(param: T): P[T];
setParams: (newParams: Partial<P>) => boolean;
emit: (eventName: 'refocus') => void;
addListener: (
eventName: string,
callback: NavigationEventCallback
) => NavigationEventSubscription;
isFocused: () => boolean;
isFirstRouteInParent: () => boolean;
router?: NavigationRouter;
dangerouslyGetParent: () => NavigationScreenProp<S> | undefined;
}
The S
is required, but it's used for state, so using:
const navigation = useNavigation<NavigationStackProp>();
doesn't solve for me :/
Is there anything new to release on other packages?
I'm using these versions:
"react-navigation": "4.0.9",
"react-navigation-hooks": "1.0.3",
"react-navigation-stack": "1.9.0"
Btw I think that this could be solved using:
export function useNavigation<NavigatorProps = any, S = any>(): NavigationScreenProp<
S & NavigationRoute
> & NavigatorProps
from hooks.
Just a suggestion sorry 😛
from hooks.
I agree with the idea that useNavigation
should take a prop in addition. #42 (comment)
At this time to avoid the error, I figured out no workaround on this problem but a (poor) downcasting as below:
import {useNavigation} from 'react-navigation-hooks';
import {NavigationStackProp} from 'react-navigation-stack';
// FIXME: workaround
export const useStackNavigation = () => useNavigation() as NavigationStackProp;
And this works fine so far.
Here is a more sophisticated downcast.
https://gist.github.com/Wintus/c7fcfda1a735e6f7f89ce4c54c1d5d8e#file-usestacknavigation-ts
from hooks.
Hey, just thinking out loud here.
For you what's the difference between useNavigation<NavigationStackProp>()
and useNavigation() as NavigationStackProp
and useStackNavigation
?
For me all those are different syntaxes to downcast to a stack navigation object. Is one really better than the other conceptually if we don't take into account the verboseness?
If you call useStackNavigation
and it returns a switch navigation, that could be misleading as well. Maybe we should have a custom hook for each type of navigator to encapsulate the casting + a runtime assertion to ensure we don't return a switch navigator when user call useStackNavigation
?
But what about custom navigators/routers (should we ask the user to create his own hook and do the casting/runtime check on his own?)
@satya164 how do you plan to solve this in v5?
from hooks.
But in such case, if we want to support custom actions/navigators, we can't do any constraint on the generic params if we want to allow const navigation = useNavigation<MyCustomNavigator<MyParams>>()
.
useNavigation<T> = () => useUnsafeNavigation() as T
is not really safer, it's just encapsulating the downcast so just feels a bit nicer to use for users.
Do we have any constraint here to apply on T that make sense in all cases (including custom navs?)
from hooks.
See the linked code for useNavigation
. The code I posted gives error because there's a constraint.
from hooks.
Thanks, will try to see what I can take from v5
Seems like you have built a typesafe route/params system, looks nice. Wonder if this can be ported to v4 without too much work but maybe i'd rather do something more simple
from hooks.
It can be ported, but it'll break all existing types of v4 so probably not worth it.
from hooks.
So no support for this until react-navigation v5?
from hooks.
@luisnaranjo733 if you find a good solution for v4, don't hesitate to send a PR
from hooks.
no solution for v5 yet?
from hooks.
I do this workaround to get stack navigator props in v5. I opened a canny feature request on canny but it sounds like its not possible with the current implementation :(
import { StackNavigationProp } from "@react-navigation/stack";
import { useNavigation as _useNavigation } from "@react-navigation/native";
/**
* Type wrapper for the useNavigation hook
*/
export const useNavigation = () => {
return (_useNavigation() as unknown) as StackNavigationProp<GlobalRouteParamList, RouteName>;
};
from hooks.
Related Issues (20)
- Proper way to use react-navigation-hooks with storybook HOT 2
- react-navigation-hooks v2 HOT 2
- setTopLevelNavigator support for hooks HOT 2
- Getting error 'from' expected HOT 2
- useFocusEffect should not retrigger on re-render HOT 8
- I can't define NavigationParams types with useNavigation HOT 1
- Reset Stack HOT 1
- Proposal: Ability to pass params for tabBarOnPress defaultHandler function HOT 1
- setParams entity change when is called HOT 1
- useFocusEffect should handle drawers HOT 4
- useNavigation shouldn't be in @react-navigation/native? HOT 3
- Open&Close Drawer HOT 1
- Hooks on the web - react-navigation is now directly imported HOT 3
- useNavigation give the warning "can't perform a React state update on an unmounted component" HOT 1
- Can I reproduce events like "onEnter/onExit" ? HOT 6
- "THIS ISSUE WAS DELETED AND BLOCKED"
- Include v5 patching for users converting from v4 to v5? HOT 1
- useNavigation not working HOT 1
- How i can re-render with useNavigationParam ? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hooks.