标签: react-navigation

带有 React-Navigation 的类型安全 navigationHandler

我的 React Native 应用程序的 Typescript 和 React Navigation 存在问题。我的项目中有以下设置,这在使用例如时为我提供了很棒的帮助和自动完成功能navigation.push()

类型

import { StackNavigationProp } from '@react-navigation/stack';

export type RootStackParamList = {
    Home: undefined;
    Content: undefined;
    List: undefined;
};

export type StackNavigationProps = StackNavigationProp<RootStackParamList>;
Run Code Online (Sandbox Code Playgroud)

用法

const navigation = useNavigation<StackNavigationProps>();
Run Code Online (Sandbox Code Playgroud)

但是,我创建了一个导航处理程序函数,该函数接受一个被馈送到navigation.push. 只要参数的类型是 type ,它就可以正常工作any

const navigationHandler = useCallback((targetScreen) => {
    navigation.push(targetScreen);
}, [navigation]);
Run Code Online (Sandbox Code Playgroud)

但我对这种类型并不满意,any并且希望它targetScreen实际上只是我在其中声明的屏幕之一RootStackParamList类型中声明的屏幕之一。我尝试了无数种方法来满足push导航对象的方法,但我被困住了。

以下尝试是最成功的,但尚未完全发挥应有的作用。它确实让我在可用屏幕上自动完成,但是push仍然不满意。

类型:

export type NavigationScreen<T extends RootStackParamList> = {
    [K in keyof …
Run Code Online (Sandbox Code Playgroud)

typescript react-native react-navigation

3
推荐指数
1
解决办法
4877
查看次数

React Native:深层链接无法与 StackNavigator 正常工作

我正在尝试在 React-Native 中进行深度链接。当应用程序在后台运行时,代码可以正常工作。但是一旦我从后台删除该应用程序并尝试使用 safari 中的链接启动它。该应用程序启动后会显示详细信息屏幕。但我在导航堆栈中找不到以前的(主)屏幕。请找到下面的代码:

/* eslint-disable react-native/no-inline-styles */
import 'react-native-gesture-handler';
import React from 'react';
import {TouchableOpacity, Text, View} from 'react-native';
import {useLinking, NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';

const HomeScreen = ({navigation}) => {
  return (
    <View
      style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      <Text>Home Screen</Text>
      <TouchableOpacity
        onPress={() => {
          navigation.navigate('Details', {itemId: 40});
        }}>
        <Text>Go to Details</Text>
      </TouchableOpacity>
    </View>
  );
};

const DetailScreen = ({route, navigation}) => {
  return (
    <View
      style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: …
Run Code Online (Sandbox Code Playgroud)

deep-linking react-native react-navigation

3
推荐指数
1
解决办法
9646
查看次数

React Native:如何防止更改屏幕时状态重置?

用户访问卡后更改屏幕时遇到问题。每当客户端访问卡、更改屏幕并返回到之前的相同组件时,组件状态集都会重置。

该应用程序的工作原理如下。客户端访问他们请求的报价列表 (QuotesRequestedListScreen)。该列表是从 Firebase 加载的,因此指示加载活动的状态首先设置为 true。加载完成后,应用程序将显示卡片中的所有数据。客户端点击卡片后,屏幕发生变化并显示卡片信息。但是,如果客户端返回到上一个屏幕,屏幕将永远显示加载活动图标,直到再次更改屏幕。

我尝试使用React Navigation 提供的状态持久性,但当我尝试返回报价列表屏幕(QuotesRequestedListScreen)时它不起作用。

有人知道在更改屏幕时保持状态的最佳方法是什么?谢谢!

主报价屏幕

const QuoteScreen = (props) => {
  
  const QuotesRequestedScreen = () => {
    return (
      <Stack.Navigator headerMode="none" initialRouteName="Quote List">
        <Stack.Screen name="Quote List" component={QuotesRequestedListScreen} />
        <Stack.Screen name="Card" component={QuoteRequestedCardScreen} />
      </Stack.Navigator>
    );
  };

  return (
    <Tab.Navigator initialRouteName="Request Quote">
      <Tab.Screen name="Request Quote" component={RequestQuoteScreen} />
      <Tab.Screen name="Quotes Requested" component={QuotesRequestedScreen} />
    </Tab.Navigator>
  );
};

export default QuoteScreen;
Run Code Online (Sandbox Code Playgroud)

报价请求列表屏幕

const QuotesRequestedListScreen = (props) => {
  //Getting userID for the useEffect
  let userId = useSelector((state) …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-native react-navigation

3
推荐指数
1
解决办法
6101
查看次数

React Navigation v5 setOptions 不起作用

我正在尝试从组件内的堆栈屏幕设置导航选项,因为我需要使用屏幕上的特定操作来渲染右侧标题按钮。问题是它不起作用。我使用的结构如下:

-StackNavigator
  -MaterialTopTabNavigator
    -tab1
    -tab2
    -tab3
Run Code Online (Sandbox Code Playgroud)

当前代码:

//My navigation
    <NavigationContainer initialState={initialState} ref={ref}>
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        //some other Stacks
        <Stack.Screen
          name="Detail"
          component={DetailTabScreen}
          options={{
            headerShown: true, //header works ok
            headerRight: () => ( //this would work
              <View style={{backgroundColor: 'red', width: 100}}/>
            )
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
Run Code Online (Sandbox Code Playgroud)

我的详细信息选项卡屏幕:

const TopTab = createMaterialTopTabNavigator()
const DetailTabScreen = () => (
  <StoreProvider>
    <SafeAreaView style={{ flex: 1 }}>
      <TopTab.Navigator
        tabBarOptions={{
         ...options
        }}
      >
        <TopTab.Screen
          name="PlanDetail"
          component={PlanDetail}
          options={{
            tabBarLabel: ({ color }: TabBarLabelProps) => (
              <Text>Detalles</Text> …
Run Code Online (Sandbox Code Playgroud)

react-native react-navigation

3
推荐指数
1
解决办法
4713
查看次数

如何使用反应导航v5在反应本机中获取当前路线名称

我只想要反应本机中当前路线或屏幕的名称,我可以在条件下使用它。我正在使用基于反应类的组件。

reactjs react-native react-navigation

3
推荐指数
1
解决办法
1万
查看次数

DrawerNavigator 在点击每个选项时始终显示选项卡栏

我试图拥有一个选项卡栏,并且每个选项卡栏都有自己的堆栈导航器。我拥有的三个选项卡是“主页配置文件设置”

我也想在抽屉里展示这三个选项。我创建了一个抽屉,但只有点击主页才会显示选项卡栏。我想显示选项卡栏,就像您按下个人资料选项卡一样,选项卡栏仍保留在那里。

带有堆栈导航器的选项卡

侧抽屉具有相同的选项

从抽屉中点击配置文件会隐藏选项卡栏

这是我的代码:

const HomeStackNavigator = createStackNavigator();
export const HomeNavigator = () => {
  return (
    <HomeStackNavigator.Navigator screenOptions={defaultNavOptions}>
      <HomeStackNavigator.Screen
        name="Home"
        component={HomeScreen}
        options={homeScreenOptions}
      />
       <HomeStackNavigator.Screen
        name="Details"
        component={DetailsScreen}
        options={detailsScreenOptions}
      />
    </HomeStackNavigator.Navigator>
  );
};

const ProfileStackNavigator = createStackNavigator();
export const ProfileNavigator = () => {
  return (
    <ProfileStackNavigator.Navigator screenOptions={defaultNavOptions}>
      <ProfileStackNavigator.Screen
        name="Profile"
        component={ProfileScreen}
        options={profileScreenOptions}
      />
       <ProfileStackNavigator.Screen
        name="EditProfile"
        component={EditProfileScreen}
        options={editProfileScreenOptions}
      />
    </ProfileStackNavigator.Navigator>
  );
};

const SettingsStackNavigator = createStackNavigator();
export const SettingsNavigator = () => {
  return (
    <SettingsStackNavigator.Navigator screenOptions={defaultNavOptions}>
      <SettingsStackNavigator.Screen
        name="Settings"
        component={SettingsScreen}
        options={settingsScreenOptions}
      />
       <SettingsStackNavigator.Screen …
Run Code Online (Sandbox Code Playgroud)

navigation-drawer react-native react-navigation react-navigation-bottom-tab

3
推荐指数
1
解决办法
3439
查看次数

如何避免附加多个事件监听器?

以下代码是否要附加多个事件侦听器,或者 React Native / expo-linking 是否只允许一次附加一个事件侦听器?

import * as Linking from 'expo-linking'
import { useIsFocused } from '@react-navigation/native'

const MyComponent = () => {
  const isFocused = useIsFocused()

  useEffect(() => {
    fetchData()
    Linking.addEventListener('url', _handleEvent)
  }, [isFocused])

  const fetchData = () => {
    // ...
  }

  const _handleEvent = () => {
    // ...
  }

  return (
    <View><View>
  )
}
Run Code Online (Sandbox Code Playgroud)

有没有办法检查事件侦听器是否已存在,以便我可以执行以下操作:

useEffect(() => {
  fetchData()
  if(!eventListenerExists){
    Linking.addEventListener('url', _handleEvent)
  }
}, [isFocused])
Run Code Online (Sandbox Code Playgroud)

javascript react-native react-navigation expo

3
推荐指数
1
解决办法
1795
查看次数

如何在 React Navigation 中使用标题按钮导航到其他页面?

如何使用标题上的按钮在屏幕之间导航?当我尝试使用标题按钮返回或导航到其他页面时,我收到相同的错误。屏幕上的按钮运行良好。

“未定义不是一个对象(评估‘navigation.navigate’)(设备)”

“未定义不是一个对象(评估‘navigation.goBack’)”

import 'react-native-gesture-handler';
import  React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import Constants from 'expo-constants';

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

//Screen 1
function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}

//Screen 2
function DetailsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, …
Run Code Online (Sandbox Code Playgroud)

react-native react-navigation

3
推荐指数
1
解决办法
5214
查看次数

React Native - 在导航上暂停视频

在我的react-native项目中,我使用react-navigation 5进行导航,使用react-native-video作为音频/视频播放器。

我的要求是,当用户导航到另一个屏幕时,音频/视频是否应该停止播放。然而,这并没有发生,音频继续播放。

我在堆栈导航器中创建了两个屏幕。视频播放器是一个单独的组件。

屏幕代码:

function MainScreen({ navigation }) {
  const [audiostatus, setAudioStatus] = useState(true);

  React.useEffect(() => {
    const unsubscribe = navigation.addListener('blur', () => {
      console.log('Leaving Home Screen');
      setAudioStatus(true);
    });

    return unsubscribe;
  }, [navigation]);

  return (
    <View style={{ flex: 1, justifyContent: 'center',backgroundColor: '#fff' }}>
      <Player tracks={TRACKS} paused={audiostatus} />
      <Button
        title="Go to Screen Without Audio"
        onPress={() => navigation.navigate('No Audio Screen')}
      />
      <Button
        title="Go to Screen With Another Audio (Love Yourself)"
        onPress={() => navigation.navigate('Another Audio Screen')}
      />
    </View>
  );
}
Run Code Online (Sandbox Code Playgroud)

播放器代码 在播放器内,我收到暂停属性来决定视频是否应该已经播放或暂停。然后播放器可以通过更改状态来控制播放。 …

reactjs react-native react-navigation react-native-video

3
推荐指数
1
解决办法
8041
查看次数

React 导航 webpack 链接“CANNOT GET /...”

我正在尝试使用 React Native 为 Web 应用程序配置 React-navigation。为此,我在 NavigationContainer 上设置了链接选项,以便我可以使用以下代码从浏览器 URL 访问我的页面:

const linking = {
  prefixes: ['http://localhost:8080/', 'http://localhost:8080', 'localhost:8080'],
  // prefixes: [prefix],
  config: {
    screens: {
      SignIn: "SignIn",
      SignUp: "SignUp",
      Landing: '*',
    },
  }
};

function AppContainer() {

  return ( 
    <NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}>
      <AppStack.Navigator>
        <AppStack.Screen name="SignIn" component={SignInPage}/>
        <AppStack.Screen name="Landing" component={LandingPage}/>
        <AppStack.Screen name="SignUp" component={SignUpPage}/>
        <AppStack.Screen name="Home" component={HomePage}/>
      </AppStack.Navigator>
    </NavigationContainer>
  );
}
Run Code Online (Sandbox Code Playgroud)

当我转到“http://localhost:8080/”时,我被重定向到“http://localhost:8080/SignIn”(这很好),并且应用程序正在运行。问题是,如果我从浏览器访问“http://localhost:8080/SignIn”,我会收到“Cannot GET /SignIn”,并且该应用程序无法正常工作...

我正在使用这些版本:

"@react-navigation/bottom-tabs": "^5.11.1",
"@react-navigation/native": "^5.8.9",
"@react-navigation/stack": "^5.12.5",
Run Code Online (Sandbox Code Playgroud)

deep-linking webpack-dev-server react-native react-navigation react-native-web

3
推荐指数
1
解决办法
1194
查看次数