React Navigation在同一个StackNavigator上导航到其他屏幕时,使组件保持重新呈现状态(React Navigation Make Component Keep Re

系统教程 行业动态 更新时间:2024-06-14 17:02:17
React Navigation在同一个StackNavigator上导航到其他屏幕时,使组件保持重新呈现状态(React Navigation Make Component Keep Re-rendering When Navigate to Other Screen On the Same StackNavigator)

我正在使用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.2

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

更多推荐

本文发布于:2023-04-21 18:27:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/e4722c631d568df9965e0c55826963aa.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组件   屏幕   状态   在同一个   React

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!