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

时间:2020-03-31 15:56:13

标签: react-native react-hooks react-navigation react-navigation-v5

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

在示例代码中,我想从XXXXXXXX更改为YYYYYYYYY

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>
)

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

enter image description here

全文:

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.

因此,如果警告提示我无法使用路由参数传递功能,该如何将功能从父母传递给孩子?

3 个答案:

答案 0 :(得分:4)

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

如果您不使用状态持久性或不使用接受参数中功能的屏幕的深层链接,则可以忽略该警告。要忽略它,可以使用YellowBox.ignoreWarnings。

因此,就我而言,我可以忽略此警告并以安全的方式传递功能,以考虑路由参数。

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

或针对本机0.63及更高版本进行反应:

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

答案 1 :(得分:2)

YellowBox在本机> 0.6中不推荐使用。使用以下代码,并且还请记住这不是主要错误。这只是一个警告

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

哦。知道它不见了。谢谢

答案 2 :(得分:0)

class MainScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      title: null
    };

    this.updateTitle = this.updateTitle.bind(this);
  }

  updateTitle(title) {
    this.setState({title: title});
  }

  render() {
    return (
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen 
          name="NewScreen"
          options={{
            headerShown: true,
            headerTitle: this.state.title
          }}>
            {(props) => <NewScreen  {...props} updateTitle={this.updateTitle}/>}
          </Stack.Screen>
        </Stack.Navigator>
      </NavigationContainer>
    );
  }
}