反应导航 useLinkTo 屏幕外部但在 NavigationContainer 内部

phi*_*ilk 1 react-native react-navigation react-navigation-v5

我感到惊讶的是useLinkTo,类似的 ( useNavigation) 只能在导航器屏幕内使用,而它们真正需要的只是NavigationContainer.

因为我的场景是一个包装整个应用程序的通知系统,其通知应该能够链接到应用程序中的其他部分。

<NavigationContainer linking={linking}>
  <Notifications>
    <RootStack/>
  </Notifications>
</NavigationContainer>
Run Code Online (Sandbox Code Playgroud)

现在它位于RootStack像这样的钩子之外useLinkTo,useNavigation不起作用并抱怨缺少上下文:

“找不到导航对象。您的组件是否位于导航器的屏幕内?”

是否有使用裸露导航容器(参考)进行深度链接的解决方法?

我尝试将Notifications提供者移至内部RootStack,但这没有帮助。

its*_*Vib 6

在文档中,提到了一种实现此目的的方法useNavigation,即在没有导航属性的情况下导航。

基本上,我们所做的是将导航容器分配给外部引用,然后使用该引用在RootStack.

在文件中/project/Navigation/RootNavigation.js

import { createRef } from 'react';

export const navigationRef = createRef();

export function navigate(name, params) {
  navigationRef.current?.navigate(name, params);
}

export function goBack() {
  navigationRef.current?.goBack();
}

export default useRootNavigation = () => ({ navigationRef, navigate, goBack });
Run Code Online (Sandbox Code Playgroud)

编辑:更多参考功能可以在这里找到:https ://reactnavigation.org/docs/navigation-container

然后在你的代码中,

import {navigationRef} from '/project/Navigation/RootNavigation';

<NavigationContainer ref={navigationRef} linking={linking}>
  <Notifications>
    <RootStack/>
  </Notifications>
</NavigationContainer> 

Run Code Online (Sandbox Code Playgroud)

然后,您可以useRootNavigation在通知组件中导入钩子来导航、返回。为了更好的解释,你可以参考https://reactnavigation.org/docs/navigating-without-navigation-prop。

然而,我认为目前这是不可能的useLinkTo。useLinkTo我也在寻找这样的使用方法。如果有人发现它,请告诉我!

编辑2:

为了复制 的行为useLinkTo,我通过参考 的源代码实现了以下内容useLinkTo:

在文件中/project/Navigation/RootNavigation.js

import { getActionFromState, getStateFromPath } from '@react-navigation/native';

/**
* Previous code
*/

export function dispatch(action) {
  navigationRef.current?.dispatch(action);
}

export function linkTo(path, config = null) {
  var state = getStateFromPath(path, config);
  var action = getActionFromState(state);
  if (action !== undefined) {
    dispatch(action);
  }
}

export default useRootNavigation = () => ({
  navigationRef,
  navigate,
  goBack,
  dispatch,
  linkTo,
});
Run Code Online (Sandbox Code Playgroud)

然后,在导航之外的任何需要使用 useLinkTo 的地方

  const navigation = useRootNavigation(); // The hook defined in RootNavigation.js

  someFunction(()=>{
    navigation.linkTo(path, linking.config);
  })

Run Code Online (Sandbox Code Playgroud)

在您(也是我的)情况下,我们必须指定链接配置,否则将使用深度链接的默认行为。