如何在 React Navigation 5 中将父函数传递给子屏幕?

mat*_*lem 11 react-native react-navigation react-hooks react-navigation-v5

最近我开始使用 React Native0.61.5和 React navigation 5.x。现在我需要将父函数传递给子屏幕。例如,我想通过按下嵌套在 StackNavigator 中的 TabNavigator 选项卡中的按钮来更改导航栏图标。以前(导航版本 3.x)我getActiveChildNavigationOptions用于满足我的需要,但现在它已被删除。所以实现这个目标的唯一方法就是将自定义函数传递给子组件。

在示例代码中,我想从 更改XXXXXXXXYYYYYYYYY

const TabA = ({ route }) => (
  <View>
    <Text>Tab A</Text>
      <Button 
        title="Change header"
        onPress={() => route.params.setHeaderRightName("YYYYYYYYY")}/>
  </View>
)

const TabB = () => <><Text>Tab B</Text></>

const Tabs = createBottomTabNavigator();
const TabsNavigator = ({ navigation }) => {
  const [headerRightName, setHeaderRightName] = useState("XXXXXXXX");

  useLayoutEffect(() => navigation.setOptions({
    headerRight: () => <MyNavIcon name={headerRightName}/>
  }), [headerRightName]);

  return (
    <Tabs.Navigator>
      <Tabs.Screen name="tab-a" component={TabA} initialParams={{ setHeaderRightName }} />
      <Tabs.Screen name="tab-b" component={TabB} />
    </Tabs.Navigator>
  );
}

const Stack = createStackNavigator();
export default App = () => (
  <NavigationContainer>
    <Stack.Navigator>
      <Stack.Screen name="tabs" component={TabsNavigator} />
      <Stack.Screen name="another-screen" component={AnotherScreen} />
    </Stack.Navigator>
  </NavigationContainer>
)
Run Code Online (Sandbox Code Playgroud)

一切正常,但我收到此警告:

在此处输入图片说明

全文:

Non-serializable values were found in the navigation state, which can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.
Run Code Online (Sandbox Code Playgroud)

那么,如果警告说我无法使用路由参数传递函数,我该如何将函数从父级传递给子级呢?

mat*_*lem 10

警告中的链接指向的文档页面说:

如果您不使用状态持久性或到接受 params 函数的屏幕的深层链接,那么您可以忽略警告。要忽略它,您可以使用 YellowBox.ignoreWarnings。

因此,就我而言,我可以忽略此警告并安全地传递认为路由参数的函数。

YellowBox.ignoreWarnings([
  'Non-serializable values were found in the navigation state',
]);
Run Code Online (Sandbox Code Playgroud)

或反应本机 0.63 及更高版本:

LogBox.ignoreLogs([
  'Non-serializable values were found in the navigation state',
]);
Run Code Online (Sandbox Code Playgroud)

  • 我讨厌这是正确的答案。 (7认同)
  • @bmovement 我也讨厌这样的解决方案。但即使是贡献者也让我确信这是正确的方法。 (3认同)

kar*_*san 5

YellowBox在 react-native > 0.6 中已弃用。使用以下代码并记住这不是主要错误。这只是一个警告

import { LogBox } from 'react-native';
LogBox.ignoreLogs([
  'Non-serializable values were found in the navigation state',
]);
Run Code Online (Sandbox Code Playgroud)

哦。知道它走了。谢谢

注意:上面的问题是通过 setState const 变量传递给屏幕的initialParams。所以我们不能通过传递函数或任何其他可执行模块initialParams,这只是传递字符串类型的数据。所以请使用下面的代码来传递函数、setvariables 等...

const [HeaderRightName,setHeaderRightName] = React.useState('');
<Tabs.Screen name="tab-a" options={{ headerShown: false }} >
           {(props) => (
                <TabA setHeaderRightName={setHeaderRightName} {...props}/>
           )}
</Tabs.Screen
Run Code Online (Sandbox Code Playgroud)