我正在使用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等都被调用。
无论如何要防止重新渲染?或者这是一种常见行为?
答案 0 :(得分:1)
这是StackNavigator
的预期行为。
在StackNavigator
中,CompletedBill
在Bill
之后声明(对象意味着无序,但此库会使用它),
当您从Bill
导航到CompletedBill
时,CompletedBill
会被推送到堆栈(其下方为Bill
,因此Bill
无法获取卸载)。
当您从CompletedBill
导航到Bill
时,会从堆栈中弹出CompletedBill
并卸载。
如果您在CompletedBill
之间切换时不希望Bill
卸载,则应使用TabNavigator
代替StackNavigator
。您可以通过设置tabBarVisible: false
in TabNavigator's navigationOptions
隐藏标签栏。