React Navigation v5:如何在子屏幕内获取父导航器的路由参数
Posted
技术标签:
【中文标题】React Navigation v5:如何在子屏幕内获取父导航器的路由参数【英文标题】:React Navigation v5: How to get route params of the parent navigator inside the child screen 【发布时间】:2020-07-22 10:16:05 【问题描述】:所以我有嵌套的导航器
主 BottomTab.Navigator
个人资料 底部标签 #1 (Stack.Navigator) 个人资料视图(屏幕) 关注者(屏幕) 以下(顶部选项卡导航器) 页面(屏幕) 组(屏幕) Feed 底部标签 #2(堆栈) 其他一些底部标签#3(堆栈)问题是当我从 Profile View Screen 导航到 Follow Navigator 时,我将一些参数传递给父 Follow Navigator,并且我希望所有这些参数都在子选项卡屏幕(页面/组)中。
但是子选项卡屏幕的路由没有得到传递给父导航器(Following Tab Navigator)的参数
有没有办法做到这一点?
这是我的代码: 个人资料堆栈
const ProfileStack = () => (
<Stack.Navigator
initialRouteName='profileView'
>
<Stack.Screen
name='profileView'
component=ProfileScreen
options=
headerMode: 'screen',
headerShown: false,
/>
<Stack.Screen
name='followers'
component=FollowersScreen
options=
headerTitle: 'Followers',
/>
<Stack.Screen
name='following'
component=FollowingTabs
options=
headerTitle: 'Following',
/>
</Stack.Navigator>
FollowingTabs
const Tabs = createMaterialTopTabNavigator();
export const FollowingTabs = () => (
<Tabs.Navigator
initialRouteName='page'
lazy
swipeEnabled
>
<Tabs.Screen
component=PageScreen
name='page'
options= tabBarLabel: '2 Pages'
/>
<Tabs.Screen
component=GroupScreen
name='groups'
options= tabBarLabel: '3 Groups'
/>
</Tabs.Navigator>
);
从 profileView 屏幕我试图导航到以下选项卡屏幕,需要传递一些参数,如下所示。
const onPressHandler = () =>
navigation.navigate('following', ** isPublicProfile, firstName **); // These parameters are passed to route of the following Tabs Navigator
;
当我尝试在子选项卡(页面/组)中读取这些参数时,这些参数是未定义的
const PageScreen = ( route ) =>
const isPublicProfile, firstName = route.params; // undefined?? Cant read parent's params
...
任何帮助将不胜感激。
编辑:我在 github (https://github.com/react-navigation/rfcs/issues/43) 上发现了这个未解决的问题,这还不可能吗?
【问题讨论】:
【参考方案1】:所以我最终按照官方 React Navigation documentation 的推荐使用了 React.Context
。更多信息请关注官方文档。
1- 使用 React 上下文并使用上下文提供程序包装导航器以将数据传递到屏幕(推荐)。
这是我的解决方案:
const DEFAULT_CONTEXT =
isPublicProfile: false,
...
;
const FollowingTabNavigatorContext = createContext(DEFAULT_CONTEXT);
在父标签导航器中
const Tabs = createMaterialTopTabNavigator();
export const FollowingTabs = ( route ) =>
const isPublicProfile = route.params;
return (
<FollowingTabNavigatorContext.Provider value= isPublicProfile >
<Tabs.Navigator
initialRouteName='pages'
lazy
swipeEnabled
>
<Tabs.Screen
component=PageScreen
name='pages'
options= tabBarLabel: '2 Pages'
/>
<Tabs.Screen
component=GroupScreen
name='groups'
options= tabBarLabel: '3 Groups'
/>
</Tabs.Navigator>
</FollowingTabNavigatorContext.Provider>
);
;
FollowingTabs.propTypes = propTypes;
FollowingTabs.defaultProps = defaultProps;
最后在我的子标签屏幕中:
export const GroupScreen = () =>
const isPublicProfile = useContext(FollowingTabNavigatorContext);
...
【讨论】:
【参考方案2】:所以这是一个不使用上下文的替代 hacky 解决方案;p
但请注意,此渲染回调解决方案是有代价的。阅读here
注意:默认情况下,React Navigation 会对屏幕组件进行优化,以防止不必要的渲染。使用渲染回调会删除这些优化。因此,如果您使用渲染回调,您需要确保为屏幕组件使用
React.memo
或React.PureComponent
,以避免出现性能问题。
const Tabs = createMaterialTopTabNavigator();
export const FollowingTabs = ( route ) =>
const isPublicProfile = route.params;
return (
<Tabs.Navigator
initialRouteName='pages'
lazy
swipeEnabled
>
<Tabs.Screen
name='pages'
options= tabBarLabel: '2 Pages'
>
() => <PageScreen isPublicProfile=isPublicProfile />
</Tabs.Screen>
<Tabs.Screen
name='groups'
options= tabBarLabel: '3 Groups'
>
() => <GroupScreen isPublicProfile=isPublicProfile />
</Tabs.Screen>
</Tabs.Navigator>
);
;
FollowingTabs.propTypes = propTypes;
FollowingTabs.defaultProps = defaultProps;
【讨论】:
【参考方案3】:编辑!!! :这仅在您第一次导航到子对象时有效。可能有一种方法可以每次都重置孩子或父母,但使用上下文可能更好......
如果有人仍然想要一个非上下文解决方案,我相信您可以使用孩子们中的initialParams
道具来做您正在寻找的事情。
假设路由有一些参数传递给它。
export const FollowingTabs = (route) => (
<Tabs.Navigator
initialRouteName='page'
lazy
swipeEnabled
>
<Tabs.Screen
component=PageScreen
name='page'
options= tabBarLabel: '2 Pages'
initialParams=route.params // Then you can grab these params using the usual route.params in the PageScreen component
/>
<Tabs.Screen
component=GroupScreen
name='groups'
options= tabBarLabel: '3 Groups'
/>
</Tabs.Navigator>
);
【讨论】:
【参考方案4】:您可以轻松地在选项卡导航器中使用 initialParams 并传递道具。 检查此解决方案。
<Stack.Screen name="Settings" >
(props) => (
<Tab.Navigator>
<Tab.Screen name="Tab1" component= Tab1
initialParams= props.route.params // <- pass params from root navigator
/>
<Tab.Screen name="Tab2" component= Tab2
initialParams= props.route.params
/>
</Tab.Navigator>
)
</Stack.Screen>
参考 https://github.com/react-navigation/rfcs/issues/43#issuecomment-610706264
【讨论】:
以上是关于React Navigation v5:如何在子屏幕内获取父导航器的路由参数的主要内容,如果未能解决你的问题,请参考以下文章
如何重置嵌套的堆栈导航导航器 react-navigation v5
将 React Navigation v4 深层链接配置迁移到 React Navigation v5 时遇到问题
是否可以使用 react-navigation (v5) 以 UIModalPresentationPageSheet 或 UIModalPresentationFormSheet 样式呈现模式?
最新版 react-navigation v5.0 上带有标题按钮的换屏
react-navigation v5 中的 Typescript StackNavigatonProps 和 Screen 道具