React Navigation 使组件在导航到同一 StackNavigator 上的其他屏幕时保持重新渲染 [英] React Navigation Make Component Keep Re-rendering When Navigate to Other Screen On the Same StackNavigator

查看:30
本文介绍了React Navigation 使组件在导航到同一 StackNavigator 上的其他屏幕时保持重新渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 react-navigation@1.5.11 中使用 react-native.

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.2

我正在使用 StackNavigator 和 TabNavigator 以及如下所示的路由器设置:

I 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 组件和 CompletedBill 组件在同一个堆栈中,用户可以通过点击右上角的图标导航到 CompletedBill 组件.

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>       

    );
  }

}

我的 CompletedBill 组件代码

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>

    );
  }

}

每次在 Bill 组件屏幕右上角图标上的用户选项卡上,它都会将它们带到 CompletedBill 组件中,并且每次当所有 componentWillMount、componentDidMount 等被调用时,整个 CompletedBill 组件都会重新渲染.

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 中,CompletedBillBill 之后声明(对象是无序的,但这个库使用了它),

In your StackNavigator, CompletedBill is declared after Bill (objects are meant to be unordered, but this library makes use of it),

当您从 Bill 导航到 CompletedBill 时,CompletedBill 会被推送到堆栈中(下面是 Bill所以 Bill 不会被卸载).

When you navigate from Bill to CompletedBill, CompletedBill is pushed to the stack (with Bill underneath it so Bill doesn't get unmounted).

当您从 CompletedBill 导航到 Bill 时,CompletedBill 从堆栈中弹出并卸载.

When you navigate from CompletedBill to Bill, CompletedBill is popped from the stack and gets unmounted.

如果您不希望 CompletedBill 在它和 Bill 之间切换时被卸载,您应该使用 TabNavigator 而不是 >StackNavigator.您可以通过在 TabNavigator 中设置 tabBarVisible: false 来隐藏标签栏navigationOptions.

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.

这篇关于React Navigation 使组件在导航到同一 StackNavigator 上的其他屏幕时保持重新渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆