Alec Bennett
Alec Bennett

Reputation: 5887

How to "lazy load" tab navigator screens now that lazy has been removed from react-navigation

The maintainers of react-navigation have removed 'lazy: true' from the library, causing all tabs to attempt to render at once (and fetches previously controlled by lazy now firing out of order).

In order to maintain similar functionality, how do you force a wait on a tab screen to not load or call fetch calls prior to being focused for the first time?

Upvotes: 7

Views: 24178

Answers (6)

Nasreen Ustad
Nasreen Ustad

Reputation: 1712

lazy={true}
  optimizationsEnabled={true}
  tabBarOptions={tabBarOptions}

the above code is important, try it

import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";
import { createStackNavigator } from "@react-navigation/stack";

const TabNavigator = createMaterialTopTabNavigator();
const Stack1 = createStackNavigator();
const Stack2 = createStackNavigator();

const ProductsScreen = (props) => {
//
return (
<TabNavigator.Navigator
  lazy={true}
  optimizationsEnabled={true}
  tabBarOptions={tabBarOptions}
>
  <TabNavigator.Screen name="HOME" component={StackScreen1} />
  <TabNavigator.Screen name="SHOP" component={StackScreen2} />
</TabNavigator.Navigator>
);
};

const tabBarOptions = {
indicatorStyle: {
height: null,
top: 0,
backgroundColor: "#ccc",
borderBottomColor: "black",
borderBottomWidth: 3,
},
activeTintColor: "black",

style: {
backgroundColor: "red",
},
labelStyle: { fontSize: 13 },
};

Upvotes: 1

SirPhemmiey
SirPhemmiey

Reputation: 641

In the new versions of React Navigation the lazy prop is set to true by default.

See https://reactnavigation.org/docs/en/bottom-tab-navigator.html#lazy

Upvotes: 0

Scientist1642
Scientist1642

Reputation: 1212

React-navigation now suports withNavigationFocus wrapper. You can use it to wrap the screen you want to prevent updating when it is not focused.

import React from 'react';
import { Text } from 'react-native';
import { withNavigationFocus } from 'react-navigation';

class LazyScreen extends React.Component {
   shouldComponentUpdate(nextProps, nextState) {
     return nextProps.isFocused;
   }

  render() {
    return <Text>{this.props.isFocused ? 'Focused' : 'Not focused' </Text>;
  }
}

export default withNavigationFocus(LazyScreen);

P.S. if you use Redux just do export default connect(mapStateToProps, mapDispatchToProps)(withNavigationFocus(LazyScreen));

Upvotes: 1

jhm
jhm

Reputation: 4539

It seems they did remove it, but have decided to add it back in v 1.1.2

https://github.com/react-navigation/react-navigation/releases/tag/v1.1.2

Thus, you should be able to pass lazy={true} in your TabNavigatorConfig object, and then tabs will not be rendered before they are active. To further optimize memory usage, you can couple this with removeClippedSubviews to free memory from inactive tabs.

Upvotes: 9

Ajith Pandian
Ajith Pandian

Reputation: 1342

You can use LazyLoading from react-navigation-utils

Upvotes: 1

Bright Lee
Bright Lee

Reputation: 2326

How about this?

const MyTab = TabNavigator({
    tab1:{screen:TabScreen1},
    tab2:{screen:TabScreen2}
}


class MainScreen extends React.Component{

    constructor(){
        super();
        this.state = {
            loading:true
        }
    }

    componentWillMount(){
        //fetch login
        //set loading:false when fetch is done
    }

    render(){
        !this.state.loading && <MyTab/>
    }
}

Upvotes: 0

Related Questions