React native 反应导航使组件在导航到同一StackNavigator上的其他屏幕时保持重新渲染

React native 反应导航使组件在导航到同一StackNavigator上的其他屏幕时保持重新渲染,react-native,react-navigation,React Native,React Navigation,我将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 => in

我将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
  }
);
const BillStack=StackNavigator({
比尔:{屏幕:比尔},
CompletedBill:{屏幕:CompletedBill}
}, 
{headerMode:'无'});
导出默认选项卡导航器(
{
票据:{screen:BillStack},
AddBill:{屏幕:AddBill},
设置:{屏幕:设置}
},
{
导航选项:({navigation})=>({
tabBarIcon:({focused,tintColor})=>{
const{routeName}=navigation.state;
让我来;
交换机(路由名称){
“法案”一案:
iconName=`ios专辑${focused?''''-outline'}`;
打破
“AddBill”案例:
iconName=`ios添加圆${聚焦?''''-outline'}`;
打破
案例“设置”:
iconName=`ios多维数据集${聚焦?'''''-outline'}`;
打破
违约:
iconName=`ios专辑${focused?''''-outline'}`;
}         
回来
} 
}),
选项卡选项:{
activeTintColor:AppStyles.defaultTextBlueColor,
InactiveIntColor:“#ABB2B9”,
showLabel:false,
风格:{
背景颜色:“#FFFFFF”,
borderTopColor:AppStyles.navbarAndTabbarBorderColor
}      
},
tabBarComponent:TabBarBottom,
tabBarPosition:'底部',
animationEnabled:没错,
swipeabled:false
}
);
Bill component和CompletedBill component位于同一堆栈上,用户可以通过右上角图标上的选项卡导航到CompletedBill component

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>       

    );
  }

}
class.Component{
渲染(){
返回(
{this.renderNavBarLeftButton()}
我的任务
this.props.navigation.navigate('CompletedBill')}>
);
}
}
我的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>

    );
  }

}
类CompletedTask扩展了React.Component{
componentWillMount(){
log('CompletedTask componentWillMount');
}
componentDidMount(){
log('CompletedTaskComponentDidMount');
}  
组件将卸载(){
log('CompletedTaskComponentWillUnmount');
}  
组件将接收道具(){
log('CompletedTaskComponentWillReceiveProps');
}  
渲染(){
返回(
this.props.navigation.dispatch({type:'navigation/BACK'})}>
我填好的账单
);
}
}
每次Bill component屏幕右上角图标上的用户选项卡,都会将它们带到Completed Bill component,每次调用所有组件时,整个Completed Bill component都会重新呈现


是否仍要防止重新渲染?或者这是一种常见行为?

这是
StackNavigator
的预期行为

在您的
StackNavigator
中,
CompletedBill
Bill
之后声明(对象是无序的,但此库使用它)

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

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

解决方案
如果您不希望在切换到
已完成票据和
票据时卸载
已完成票据
,则应使用
选项卡导航器
,而不是
堆栈导航器
。您可以通过设置隐藏选项卡栏。

这很糟糕,因为我相信大多数人都不希望出现这种行为