如何修复自定义反应导航组件中的“ navigation.state未定义”?

时间:2019-10-31 21:01:35

标签: react-native navigation react-navigation react-native-paper

我正在尝试使用tabBarComponent中的createMaterialTopTabNavigator为我的React Native应用使用自定义组件("react-native-tabs"属性),该组件是{{1}中的BottomNavigation }}。

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

我有3条主要代码:   BottomNavigation

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行),但我看不到原因。

1 个答案:

答案 0 :(得分:0)

我认为这里存在错误:tabBarComponent: ({ props }) => <CustomTabNavigation {...props} />应该是tabBarComponent : props => <CustomTabNavigation {...props} />或仅仅是tabBarComponent: CustomTabNavigation

纸张上的

BottomNavigation不是标签栏组件,而是完整的标签导航组件。您可以通过不渲染内容来像标签栏一样使用它。

但是请考虑,无论是Android还是iOS设计准则都没有在底部选项卡中添加滑动手势,因此UX会不一致。通常,顶部标签栏具有滑动手势,因为用手指更难到达顶部栏。