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

react-navigation useLinkTo outside screen but inside NavigationContainer

令我惊讶的是 useLinkTo 等 (useNavigation) 只能在导航器屏幕内使用,而它们真正需要的只是 [=13] 设置的导航上下文=].

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

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

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

"Couldn't find a navigation object. Is your component inside a screen in a navigator?"

是否有使用裸骨 NavigationContainer(参考)进行深度 linking 的解决方法?

我试图将 Notifications 提供程序移动到 RootStack 中,但这没有帮助。

在文档中,提到了 useNavigation 实现此目的的方法,即 Navigating without the navigation prop

基本上,我们所做的是将导航容器分配给外部引用,然后使用该引用在 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 });

编辑:ref 的更多函数可以在这里找到:https://reactnavigation.org/docs/navigation-container

然后在你的代码中,

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

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

然后,您可以在 Notification 组件中导入 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,
});

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

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

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

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