我试图在反应导航中的DrawerNavigator上获得一个 Headers . 我在StackNavigator中有一个DrawerNavigator,抽屉中的所有页面都有一个类似的 Headers ( Headers 除外) .

const HomeNavigator = createStackNavigator(
  {
    HomeScreen: { screen: HomeScreen },
    HomeRouter: { screen: HomeRouter }
  },
  {
    initialRoute: 'HomeScreen',
  });

HomeRouter 是抽屉 .

const HomeRouter = createDrawerNavigator(
  {
    Agenda: { screen: Agenda },
    Nieuws: { screen: Nieuws },
    ....
  },
  {
    contentComponent: SideBar,
    drawerWidth: 300,
  }
);

现在,这在抽屉中的每个屏幕上都给出了标准 Headers ,但这不是我想要的 Headers . 我想定制它,这很困难 . 我尝试了两种方法:

  • 将 Headers 放在DrawerNavigator上 . 我无法找到办法做到这一点 . 将navigationOptions放在StackNavigator中的屏幕上没有任何效果 . 我在这里找到了一个解决方案:https://stackoverflow.com/a/46808712(用 withHeader 函数包装,但在react-navigation版本2中不起作用 . 它会出错 .

First Question: Why does this not work?

  • 摆脱HomeRouter上的 Headers ,并将 Headers 放在抽屉中的每个屏幕上 . 为了实现这一点,这些屏幕必须包含在StackNavigator中 . 这种方法有效,但每个屏幕都需要样板代码,违反DRY原则 .

基本上代码变成:

const HomeNavigator = createStackNavigator(
  {
    HomeScreen: { screen: HomeScreen },
    HomeRouter: { screen: HomeRouter,
                  navigationOptions: () => ({
                    header: null
                  })
                }
  },
  {
    initialRoute: 'HomeScreen',
  });

然后在 HomeRouter

const wrap = (name, screen) => {
  return(
    createStackNavigator({
      [name]: { screen: screen }
    })
  );
};

const HomeRouter = createDrawerNavigator(
  {
    Agenda: { screen: wrap('Agenda', Agenda)},
    ...

屏幕定义了自己的 Headers :

class Agenda extends Component {
  static navigationOptions = () => ({
    header: (
      <MenuHeader title="Agenda" />
    )
  });

  render() { .....

这个解决方案有效,但现在我试图将头代码分解并将其放入包装函数中 .

我试图将navigationOptions作为属性放在 Agenda 屏幕上 . 如果我在定义组件的地方执行此操作,则此方法有效:

class Agenda extends Component {
  static navigationOptions = () => ({
    header: (
      <MenuHeader title="Agenda" />
    )
  });

  render() { ...
}

Agenda.navigationOptions = () => ({
    header: (
      <MenuHeader title="Agenda" />
    )
  });

export default Agenda;

该解决方案有效 . 但仍然使用样板代码 . 所以我想将属性 navigationOptions 设置为包装函数 . 但后来我收到一个错误:

此代码失败:

import Agenda from '../Pages/Agenda';

Agenda.navigationOptions = () => ({
        header: (
          <MenuHeader title="Agenda" />
        )
      });

这给出了错误"Invariant Violation. Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined."

Second Question: So why does it work when applied before the export, but not after the import? Is the imported component not the same as the exported one? I also tried it with named export/import but that does not make a difference.