【问题标题】:React Navigation Make Component Keep Re-rendering When Navigate to Other Screen On the Same StackNavigator当导航到同一 StackNavigator 上的其他屏幕时,React Navigation 使组件保持重新渲染
【发布时间】:2018-04-29 11:23:51
【问题描述】:

我正在使用 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 组件在同一个堆栈中,用户可以通过点击右上角的图标导航到 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 等都被调用。

无论如何要防止重新渲染?或者这是一种常见的行为?

【问题讨论】:

    标签: react-native react-navigation


    【解决方案1】:

    这是StackNavigator 的预期行为。

    在您的StackNavigator 中,CompletedBillBill 之后声明(对象是无序的,但这个库利用了它),

    当您从Bill 导航到CompletedBill 时,CompletedBill 被推入堆栈(Bill 在其下方,因此Bill 不会被卸载)。

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

    解决方案

    如果您不想在CompletedBillBill 之间切换时卸载它,您应该使用TabNavigator 而不是StackNavigator。您可以通过设置tabBarVisible: false in TabNavigator's navigationOptions来隐藏标签栏。

    【讨论】:

    • 这很糟糕,因为我相信大多数人都不希望这种行为
    猜你喜欢
    • 1970-01-01
    • 2019-03-19
    • 2019-03-14
    • 1970-01-01
    • 2019-11-21
    • 2020-06-09
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    相关资源
    最近更新 更多