我正在使用react-native与react-navigation@1.5.11。
Environment: OS: macOS High Sierra 10.13.1 Node: 8.9.2 Yarn: 1.5.1 npm: 5.8.0 Watchman: 4.9.0 Xcode: Xcode 9.1 Build version 9B55 Android Studio: 3.1 AI-173.4720617 Packages: (wanted => installed) react: 16.3.1 => 16.3.1 react-native: 0.55.2 => 0.55.2我正在使用StackNavigator和TabNavigator以及我的路由器设置,如下所示:
const BillStack = StackNavigator({ Bill: { screen: Bill }, CompletedBill: { screen: CompletedBill } }, { headerMode: 'none' }); export default TabNavigator( { Bill: { screen: BillStack }, AddBill: { screen: AddBill }, Setting: { screen: Setting } }, { navigationOptions: ({ navigation }) => ({ tabBarIcon: ({ focused, tintColor }) => { const { routeName } = navigation.state; let iconName; switch(routeName) { case 'Bill': iconName = `ios-albums${focused ? '' : '-outline'}`; break; case 'AddBill': iconName = `ios-add-circle${focused ? '' : '-outline'}`; break; case 'Setting': iconName = `ios-cube${focused ? '' : '-outline'}`; break; default: iconName = `ios-albums${focused ? '' : '-outline'}`; } return <IconIonicons name={iconName} size={27} color={tintColor} />; } }), tabBarOptions: { activeTintColor: AppStyles.defaultTextBlueColor, inactiveTintColor: '#ABB2B9', showLabel: false, style: { backgroundColor: '#FFFFFF', borderTopColor: AppStyles.navbarAndTabbarBorderColor } }, tabBarComponent: TabBarBottom, tabBarPosition: 'bottom', animationEnabled: true, swipeEnabled: false } );Bill组件和CompletedBill组件位于同一堆栈中,用户可以通过右上角的图标上的Tab键导航到CompletedBill组件。
class Bill extends React.Component { render () { return ( <Container style={AppStyles.defaultScreenStyle}> <Header style={AppStyles.defaultHeaderStyle}> {this.renderNavBarLeftButton()} <Body> <Title style={AppStyles.headerTextStyle}>My Task</Title> </Body> <Right> <Button transparent onPress={() => this.props.navigation.navigate('CompletedBill')}> <IconIonicons name='ios-archive-outline' size={35} color="#263238"/> </Button> </Right> </Header> </Container> ); } }我的CompletedBill组件代码
class CompletedTask extends React.Component { componentWillMount() { console.log('CompletedTask componentWillMount'); } componentDidMount() { console.log('CompletedTask componentDidMount'); } componentWillUnmount () { console.log('CompletedTask componentWillUnmount'); } componentWillReceiveProps() { console.log('CompletedTask componentWillReceiveProps'); } render () { return ( <Container style={AppStyles.defaultScreenStyle}> <Header style={AppStyles.defaultHeaderStyle}> <Left> <Button transparent onPress={() => this.props.navigation.dispatch({ type: 'Navigation/BACK' })}> <IconIonicons name='ios-arrow-back' size={30}/> </Button> </Left> <Body style={{flex: 3}}> <Title style={AppStyles.headerTextStyle}>My Completed Bill</Title> </Body> <Right> <Button transparent> </Button> </Right> </Header> </Container> ); } }Bill组件屏幕右上角的每个用户选项卡都会将它们带到CompletedBill组件,每次整个CompletedBill组件都会在所有componentWillMount,componentDidMount等被调用时重新呈现。
无论如何,以防止重新渲染? 或者这是一种常见的行为?
I am using react-native with react-navigation@1.5.11.
Environment: OS: macOS High Sierra 10.13.1 Node: 8.9.2 Yarn: 1.5.1 npm: 5.8.0 Watchman: 4.9.0 Xcode: Xcode 9.1 Build version 9B55 Android Studio: 3.1 AI-173.4720617 Packages: (wanted => installed) react: 16.3.1 => 16.3.1 react-native: 0.55.2 => 0.55.2I am using StackNavigator and TabNavigator and my router setup like below:
const BillStack = StackNavigator({ Bill: { screen: Bill }, CompletedBill: { screen: CompletedBill } }, { headerMode: 'none' }); export default TabNavigator( { Bill: { screen: BillStack }, AddBill: { screen: AddBill }, Setting: { screen: Setting } }, { navigationOptions: ({ navigation }) => ({ tabBarIcon: ({ focused, tintColor }) => { const { routeName } = navigation.state; let iconName; switch(routeName) { case 'Bill': iconName = `ios-albums${focused ? '' : '-outline'}`; break; case 'AddBill': iconName = `ios-add-circle${focused ? '' : '-outline'}`; break; case 'Setting': iconName = `ios-cube${focused ? '' : '-outline'}`; break; default: iconName = `ios-albums${focused ? '' : '-outline'}`; } return <IconIonicons name={iconName} size={27} color={tintColor} />; } }), tabBarOptions: { activeTintColor: AppStyles.defaultTextBlueColor, inactiveTintColor: '#ABB2B9', showLabel: false, style: { backgroundColor: '#FFFFFF', borderTopColor: AppStyles.navbarAndTabbarBorderColor } }, tabBarComponent: TabBarBottom, tabBarPosition: 'bottom', animationEnabled: true, swipeEnabled: false } );Bill component and CompletedBill component are on the same stack and user can navigate to CompletedBill component by tabbing on the upper right hand icon.
class Bill extends React.Component { render () { return ( <Container style={AppStyles.defaultScreenStyle}> <Header style={AppStyles.defaultHeaderStyle}> {this.renderNavBarLeftButton()} <Body> <Title style={AppStyles.headerTextStyle}>My Task</Title> </Body> <Right> <Button transparent onPress={() => this.props.navigation.navigate('CompletedBill')}> <IconIonicons name='ios-archive-outline' size={35} color="#263238"/> </Button> </Right> </Header> </Container> ); } }My CompletedBill component code
class CompletedTask extends React.Component { componentWillMount() { console.log('CompletedTask componentWillMount'); } componentDidMount() { console.log('CompletedTask componentDidMount'); } componentWillUnmount () { console.log('CompletedTask componentWillUnmount'); } componentWillReceiveProps() { console.log('CompletedTask componentWillReceiveProps'); } render () { return ( <Container style={AppStyles.defaultScreenStyle}> <Header style={AppStyles.defaultHeaderStyle}> <Left> <Button transparent onPress={() => this.props.navigation.dispatch({ type: 'Navigation/BACK' })}> <IconIonicons name='ios-arrow-back' size={30}/> </Button> </Left> <Body style={{flex: 3}}> <Title style={AppStyles.headerTextStyle}>My Completed Bill</Title> </Body> <Right> <Button transparent> </Button> </Right> </Header> </Container> ); } }Everytime user tab on the upper right icon on Bill component screen, it will bring them to CompletedBill component and everytime the entire CompletedBill component re-render as all the componentWillMount, componentDidMount and etc get called.
Anyway to prevent from re-rendering? Or it's a common behavior?
最满意答案
这是StackNavigator的预期行为。
在您的StackNavigator , CompletedBill在Bill之后声明(对象意味着无序,但是该库使用它),
当您从Bill浏览到CompletedBill , CompletedBill被推入堆栈( Bill下方, Bill无法卸载)。
当您从CompletedBill导航到Bill , CompletedBill将从堆栈弹出并取消挂载。
解
如果您不希望在它与Bill之间切换时卸载CompletedBill ,则应该使用TabNavigator而不是StackNavigator 。 您可以通过在TabNavigator的navigationOptions设置tabBarVisible: false来隐藏选项卡栏。
This is the intended behavior of StackNavigator.
In your StackNavigator, CompletedBill is declared after Bill (objects are meant to be unordered, but this library makes use of it),
When you navigate from Bill to CompletedBill, CompletedBill is pushed to the stack (with Bill underneath it so Bill doesn't get unmounted).
When you navigate from CompletedBill to Bill, CompletedBill is popped from the stack and gets unmounted.
Solution
If you don't want CompletedBill to be unmounted when switching between it and Bill, you should use a TabNavigator instead of StackNavigator. You can hide the tab bar by setting tabBarVisible: false in TabNavigator's navigationOptions.
更多推荐
发布评论