React Native 如何使用导航,从堆栈外部的组件导航,导航

qoefvg9y  于 2022-12-14  发布在  React
关注(0)|答案(6)|浏览(153)

我有一个使用React native的应用程序,其中我使用了react-navigation(5.2.9)。
我构建了一个Stack.Navigator,我在其中放置了我的屏幕,但我希望Footer组件位于外部,以便它在所有屏幕中呈现。问题是,我无法从页脚导航,而这正是我需要做的,因为页脚有几个按钮,它们应该改变屏幕:

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>
  );
};

如何将导航属性传递给页脚组件?

z2acfund

z2acfund1#

试试这个:
创建一个新文件,命名为:RootNavigation.js
第一个
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/

u4vypkhs

u4vypkhs2#

Stack.Screen组件之外的组件不接收导航属性。因此,在这种情况下,您必须使用脚注组件中的refs来获取NavigationContainer,如下所示:
1.使用const myRef = React.createRef()创建引用
1.将其传递给<NavigationContainer ref={myRef}>,然后
1.使用引用进行导航,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)

hfyxw5xn

hfyxw5xn3#

来自文档. 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)}
    />
  );
}
w8f9ii69

w8f9ii694#

最后我构建了一个名为screen的组件,它只会 Package screen的内容,并根据属性呈现页眉/页脚:

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>

如果我不能解决这个问题,我觉得这是最好的办法。

tyg4sfes

tyg4sfes5#

screenOptions中提取navigation的简单技巧。

function NavWrapper() {
  const navigatorRef = useRef<any>();
  <Tab.Navigator
    screenOptions={({ navigation: nav }) => navigatorRef.current = nav}
  >
    <Tab.Screen name="screen1" />
  </Tab.Navigator>
}
9fkzdhlc

9fkzdhlc6#

我使用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" });

相关问题