首页 > 解决方案 > 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: 'center',
      }}>
      <Text>Details Screen</Text>
      <Text>Item Id: {route.params.itemId}</Text>
      <TouchableOpacity onPress={() => navigation.goBack()}>
        <Text>Go Back</Text>
      </TouchableOpacity>
    </View>
  );
};

const Stack = createStackNavigator();

const App = () => {
  const ref = React.useRef();
  const {getInitialState} = useLinking(ref, {
    prefixes: ['deeplink://'],
    config: {
      initialRouteName: 'Home',
      Home: 'Home',
      Details: {
        path: 'Details/:itemId',
        parse: {
          itemId: null,
        },
      },
    },
    getPathFromState(state, config) {
      console.log(state);
    },
  });

  const [isReady, setIsReady] = React.useState(false);
  const [initialState, setInitialState] = React.useState();

  React.useEffect(() => {
    Promise.race([
      getInitialState(),
      new Promise((resolve) => setTimeout(resolve, 150)),
    ])
      .catch((e) => {
        console.error(e);
      })
      .then((state) => {
        if (state !== undefined) {
          setInitialState(state);
        }
        setIsReady(true);
      });
  }, [getInitialState]);

  if (!isReady) {
    return null;
  }
  return (
    <NavigationContainer
      fallback={<Text>Loading...</Text>}
      initialState={initialState}
      ref={ref}>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;

在 Safari 中使用“deeplink://Details/86”启动应用程序。

标签: react-nativereact-navigationdeep-linking

解决方案


首先,更新到最新版本,@react-navigation/native然后遵循链接文档:https ://reactnavigation.org/docs/configuring-links/

useLinking您可以将linkingprop 传递给NavigationContainer组件,而不是。然后将您的配置更改为以下内容:

const App = () => {
  const linking = {
    prefixes: ["deeplink://"],
    config: {
      initialRouteName: "Home",
      screens: {
        Home: {
          path: "home",
        },
        Details: {
          path: "details/:itemId"
        }
      }
    }
  };

  return (
    <NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

然后您可以打开类似deeplink://home或的链接deeplink://details/someid


推荐阅读