如何在自定义反应导航组件中修复'navigation.state未定义?'

问题描述 投票:0回答:1

[我正在尝试使用tabBarComponent中的createMaterialTopTabNavigator为我的React Native应用程序使用自定义组件("react-native-tabs"属性),该组件为BottomNavigation中的"react-native-paper"

我已经复制了https://github.com/react-navigation/material-bottom-tabs的几乎所有代码,因为这是我发现使用BottomNavigation作为自定义组件的唯一来源

我有3个主要代码段:TabNavigator (component)

class CustomTabNavigator extends React.Component {
_getColor = ({ route }) => {
  const { descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const options = descriptor.options;

  if (this.context === 'dark' && options.tabBarColorDark) {
    return options.tabBarColorDark;
  } else if (options.tabBarColorLight) {
    return options.tabBarColorLight;
  } else {
    return options.tabBarColor;
  }
};

_getactiveColor = () => {
  let { activeColor, activeColorLight, activeColorDark } = this.props;

  if (this.context === 'dark' && activeColorDark) {
    return activeColorDark;
  } else if (activeColorLight) {
    return activeColorLight;
  } else {
    return activeColor;
  }
};

_getInactiveColor = () => {
  let { inactiveColor, inactiveColorLight, inactiveColorDark } = this.props;

  if (this.context === 'dark' && inactiveColorDark) {
    return inactiveColorDark;
  } else if (inactiveColorLight) {
    return inactiveColorLight;
  } else {
    return inactiveColor;
  }
};

_getBarStyle = () => {
  let { barStyle, barStyleLight, barStyleDark } = this.props;

  return [barStyle, this.context === 'dark' ? barStyleDark : barStyleLight];
};

_isVisible() {
  const { navigation, descriptors } = this.props;
  const { state } = navigation;
  const route = state.routes[state.index];
  const options = descriptors[route.key].options;
  return options.tabBarVisible;
}

_renderIcon = ({
  route,
  focused,
  color,
}) => {
  return this.props.renderIcon({ route, focused, tintColor: color });
};

render() {
  const {
    navigation,
    descriptors,
    ...rest
  } = this.props;

  const activeColor = this._getactiveColor();
  const inactiveColor = this._getInactiveColor();
  const barStyle = this._getBarStyle();

  const isVisible = this._isVisible();
  const extraStyle =
    isVisible === false
      ? {
          display: 'none',
          position: undefined,
        }
      : null;

  return (
    <BottomNavigation
      {...rest}
      activeColor={activeColor}
      inactiveColor={inactiveColor}
      renderIcon={this._renderIcon}
      barStyle={[barStyle, extraStyle]}
      navigationState={navigation.state}
      getColor={this._getColor}
    />
  )
}
}

TabNavigation (navigator)

class CustomTabNavigation extends React.Component {
_renderScene = ({ route }) => {
  const { screenProps, descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const TabComponent = descriptor.getComponent();
  return (
    <SceneView
      screenProps={screenProps}
      navigation={descriptor.navigation}
      component={TabComponent}
    />
  );
};

_renderIcon = ({
  route,
  focused,
  tintColor,
  horizontal = false,
}) => {
  const { descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const options = descriptor.options;

  if (options.tabBarIcon) {
    return typeof options.tabBarIcon === 'function'
      ? options.tabBarIcon({ focused, tintColor, horizontal })
      : options.tabBarIcon;
  }

  return null;
};

_getLabelText = ({ route }) => {
  const { descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const options = descriptor.options;

  if (options.tabBarLabel) {
    return options.tabBarLabel;
  }

  if (typeof options.title === 'string') {
    return options.title;
  }

  return route.routeName;
};

_getAccessibilityLabel = ({ route }) => {
  const { descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const options = descriptor.options;

  if (typeof options.tabBarAccessibilityLabel !== 'undefined') {
    return options.tabBarAccessibilityLabel;
  }

  const label = this._getLabelText({ route });

  if (typeof label === 'string') {
    const { routes } = this.props.navigation.state;
    return `${label}, tab, ${routes.indexOf(route) + 1} of ${
      routes.length
    }`;
  }

  return undefined;
};

_getTestID = ({ route }) => {
  const { descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const options = descriptor.options;

  return options.tabBarTestID;
};

_getBadge = ({ route }) => {
  const { descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const options = descriptor.options;

  return options.tabBarBadge;
};

_makeDefaultHandler = ({
  route,
  navigation,
}) => () => {
  if (navigation.isFocused()) {
    if (route.hasOwnProperty('index') && route.index > 0) {
      navigation.dispatch(StackActions.popToTop({ key: route.key }));
    } else {
      navigation.emit('refocus');
    }
  } else {
    this._jumpTo(route.routeName);
  }
};

_handleTabPress = ({ route }) => {
  this._isTabPress = true;
  Promise.resolve().then(() => (this._isTabPress = false));

  const { descriptors } = this.props;
  const descriptor = descriptors[route.key];
  const { navigation, options } = descriptor;

  const defaultHandler = this._makeDefaultHandler({ route, navigation });

  if (options.tabBarOnPress) {
    options.tabBarOnPress({ navigation, defaultHandler });
  } else {
    defaultHandler();
  }
};

_handleIndexChange = index => {
  if (this._isTabPress) {
    this._isTabPress = false;
    return;
  }

  this._jumpTo(this.props.navigation.state.routes[index].routeName);
};

_jumpTo = routeName => {
  const { navigation } = this.props;

  navigation.dispatch(
    SwitchActions.jumpTo({
      routeName,
      key: navigation.state.key,
    })
  );
};

_isTabPress = false;

render() {
  const {
    descriptors,
    navigation,
    screenProps,
    navigationConfig,
  } = this.props;
  const { state } = navigation;
  const route = state.routes[state.index];
  const descriptor = descriptors[route.key];
  const options = {
    ...navigationConfig,
    ...descriptor.options,
  };

  return (
    <CustomTabNavigator
      {...options}
      getLabelText={this._getLabelText}
      getAccessibilityLabel={this._getAccessibilityLabel}
      getTestID={this._getTestID}
      getBadge={this._getBadge}
      renderIcon={this._renderIcon}
      renderScene={this._renderScene}
      onIndexChange={this._handleIndexChange}
      onTabPress={this._handleTabPress}
      navigation={navigation}
      descriptors={descriptors}
      screenProps={screenProps}
    />
  );
}
}

Main navigation

const TabNavigator = createStackNavigator(
{
  TabsStack: {
    ...,
    {
      ...,
      tabBarComponent: ({ props }) => <CustomTabNavigation {...props} />
    })
  },
}
);

我希望能够使用“反应导航”中的swipeEnabled中的createMaterialTopTabNavigator功能(到每个屏幕的动画过渡),以及一个外观更好的标签栏,但是它说'navigation.state is undefined'的渲染功能(第CustomTabNavigation行)中的const { state } = navigation;,但我看不到原因。

react-native navigation react-navigation react-native-paper
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.