如何从 stack.navigation 之外的组件使用 navigation.navigate
How to use navigation.navigate from a component outside the stack.navigation
我有一个使用 React native 的应用程序,我正在使用 react-navigation (5.2.9)。
我构建了一个 Stack.Navigator 屏幕,但我希望页脚组件位于外部,以便在所有屏幕中呈现。问题是,我无法从页脚导航,这是我需要做的,因为页脚有几个应该改变屏幕的按钮:
const Stack = createStackNavigator();
const App = () => {
return (
<Provider store={store}>
<NavigationContainer>
<Header />
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false
}}
/>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{
headerShown: false
}}
/>
</Stack.Navigator>
<Footer />
</NavigationContainer>
</Provider>
);
};
如何将导航道具传递给页脚组件?
来自文档。
https://reactnavigation.org/docs/connecting-navigation-prop/
import * as React from 'react';
import { Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';
function GoToButton({ screenName }) {
const navigation = useNavigation();
return (
<Button
title={`Go to ${screenName}`}
onPress={() => navigation.navigate(screenName)}
/>
);
}
我最终构建了一个名为 screen 的组件,它只会包装屏幕的内容并根据道具呈现 header/footer:
import React from 'react';
import { View } from 'native-base';
import style from './style';
import Footer from '../../footer';
import Header from '../../header';
const Screen = ({
footer,
header,
children,
navigation
}) => (
<View style={style.screen}>
{ header && <Header navigation={navigation} />}
{ children }
{ footer && <Footer navigation={navigation} />}
</View>
);
export default Screen;
并像这样包装我的应用程序的屏幕:
<Screen header footer navigation={navigation}>
... screen content
</Screen>
如果我无法解决这个问题,我觉得这是最好的方法。
Stack.Screen
组件之外的组件不接收导航道具。所以在这种情况下,您必须在页脚组件中使用 refs 来获取 NavigationContainer
,如下所示:
- 使用
const myRef = React.createRef()
创建一个 ref
- 将其传递给
<NavigationContainer ref={myRef}>
,然后
- 使用该 ref 进行导航,
myRef.current?.navigate(name, params)
。
都解释清楚了here。此处的文档将 ref 的创建分隔在一个新文件中,以允许您导入 ref 而不会出现依赖循环/问题。正如文档所述,您现在可以在任何 js 模块中调用 RootNavigation.navigate('ChatScreen', { userName: 'Lucy' });
,而不仅仅是在 React 组件中。
虽然在你的情况下,你不需要单独文件中的引用。
const Stack = createStackNavigator();
const navigationRef = React.createRef();
const App = () => {
return (
<Provider store={store}>
<NavigationContainer ref={navigationRef}>
<Header />
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false
}}
/>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{
headerShown: false
}}
/>
</Stack.Navigator>
<Footer navigationRef={navigationRef}/>
</NavigationContainer>
</Provider>
);
};
并在 <Footer/>
中使用 navigationRef.current?.navigate(name, params)
试试这个:
创建一个名为:RootNavigation.js
的新文件
// RootNavigation.js
import * as React from 'react';
export const navigationRef = React.createRef();
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
// file where you have the navigation
import {navigationRef} from './path/to/RootNavigation';
<NavigationContainer ref={navigationRef}>
.....
<Footer />
</NavigationContainer>
而Footer.js应该是这样的:
// Footer.js
import React from 'react';
import {View, Button} from 'react-native';
import * as RootNavigation from './path/to/RootNavigation';
const Footer= () => {
return (
<View>
<Button
title={'Go to'}
onPress={() =>
RootNavigation.navigate('screenName ', {userName: 'Lucy'})
}
/>
</View>
);
};
export default Footer;
有关详细信息,您可以阅读文档。 https://reactnavigation.org/docs/navigating-without-navigation-prop/
从 screenOptions
中提取 navigation
的简单技巧。
function NavWrapper() {
const navigatorRef = useRef<any>();
<Tab.Navigator
screenOptions={({ navigation: nav }) => navigatorRef.current = nav}
>
<Tab.Screen name="screen1" />
</Tab.Navigator>
}
我使用 React 上下文通过全局状态解决了这个问题 API:
// When enter in the HomeScreen:
const { setGlobalNavigation, globalNavigation } = useGlobalContext();
const navigation = useNavigation<RemindersNavigationProp>();
useEffect(() => {
if (setGlobalNavigation && !globalNavigation) setGlobalNavigation(navigation);
}, [setGlobalNavigation, globalNavigation, navigation]);
// When want to use:
const { globalNavigation } = useGlobalContext();
const handleNavigate = () =>
globalNavigation.navigate("contactsStack", { screen: "newContact" });
我有一个使用 React native 的应用程序,我正在使用 react-navigation (5.2.9)。
我构建了一个 Stack.Navigator 屏幕,但我希望页脚组件位于外部,以便在所有屏幕中呈现。问题是,我无法从页脚导航,这是我需要做的,因为页脚有几个应该改变屏幕的按钮:
const Stack = createStackNavigator();
const App = () => {
return (
<Provider store={store}>
<NavigationContainer>
<Header />
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false
}}
/>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{
headerShown: false
}}
/>
</Stack.Navigator>
<Footer />
</NavigationContainer>
</Provider>
);
};
如何将导航道具传递给页脚组件?
来自文档。 https://reactnavigation.org/docs/connecting-navigation-prop/
import * as React from 'react';
import { Button } from 'react-native';
import { useNavigation } from '@react-navigation/native';
function GoToButton({ screenName }) {
const navigation = useNavigation();
return (
<Button
title={`Go to ${screenName}`}
onPress={() => navigation.navigate(screenName)}
/>
);
}
我最终构建了一个名为 screen 的组件,它只会包装屏幕的内容并根据道具呈现 header/footer:
import React from 'react';
import { View } from 'native-base';
import style from './style';
import Footer from '../../footer';
import Header from '../../header';
const Screen = ({
footer,
header,
children,
navigation
}) => (
<View style={style.screen}>
{ header && <Header navigation={navigation} />}
{ children }
{ footer && <Footer navigation={navigation} />}
</View>
);
export default Screen;
并像这样包装我的应用程序的屏幕:
<Screen header footer navigation={navigation}>
... screen content
</Screen>
如果我无法解决这个问题,我觉得这是最好的方法。
Stack.Screen
组件之外的组件不接收导航道具。所以在这种情况下,您必须在页脚组件中使用 refs 来获取 NavigationContainer
,如下所示:
- 使用
const myRef = React.createRef()
创建一个 ref
- 将其传递给
<NavigationContainer ref={myRef}>
,然后 - 使用该 ref 进行导航,
myRef.current?.navigate(name, params)
。
都解释清楚了here。此处的文档将 ref 的创建分隔在一个新文件中,以允许您导入 ref 而不会出现依赖循环/问题。正如文档所述,您现在可以在任何 js 模块中调用 RootNavigation.navigate('ChatScreen', { userName: 'Lucy' });
,而不仅仅是在 React 组件中。
虽然在你的情况下,你不需要单独文件中的引用。
const Stack = createStackNavigator();
const navigationRef = React.createRef();
const App = () => {
return (
<Provider store={store}>
<NavigationContainer ref={navigationRef}>
<Header />
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerShown: false
}}
/>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{
headerShown: false
}}
/>
</Stack.Navigator>
<Footer navigationRef={navigationRef}/>
</NavigationContainer>
</Provider>
);
};
并在 <Footer/>
中使用 navigationRef.current?.navigate(name, params)
试试这个:
创建一个名为:RootNavigation.js
的新文件// RootNavigation.js
import * as React from 'react';
export const navigationRef = React.createRef();
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
// file where you have the navigation
import {navigationRef} from './path/to/RootNavigation';
<NavigationContainer ref={navigationRef}>
.....
<Footer />
</NavigationContainer>
而Footer.js应该是这样的:
// Footer.js
import React from 'react';
import {View, Button} from 'react-native';
import * as RootNavigation from './path/to/RootNavigation';
const Footer= () => {
return (
<View>
<Button
title={'Go to'}
onPress={() =>
RootNavigation.navigate('screenName ', {userName: 'Lucy'})
}
/>
</View>
);
};
export default Footer;
有关详细信息,您可以阅读文档。 https://reactnavigation.org/docs/navigating-without-navigation-prop/
从 screenOptions
中提取 navigation
的简单技巧。
function NavWrapper() {
const navigatorRef = useRef<any>();
<Tab.Navigator
screenOptions={({ navigation: nav }) => navigatorRef.current = nav}
>
<Tab.Screen name="screen1" />
</Tab.Navigator>
}
我使用 React 上下文通过全局状态解决了这个问题 API:
// When enter in the HomeScreen:
const { setGlobalNavigation, globalNavigation } = useGlobalContext();
const navigation = useNavigation<RemindersNavigationProp>();
useEffect(() => {
if (setGlobalNavigation && !globalNavigation) setGlobalNavigation(navigation);
}, [setGlobalNavigation, globalNavigation, navigation]);
// When want to use:
const { globalNavigation } = useGlobalContext();
const handleNavigate = () =>
globalNavigation.navigate("contactsStack", { screen: "newContact" });