How can i reload a screen already loaded in a BottomTabNavigator?

Viewed 445

I have 5 screens inside a BottomTabNavigator, one of them list some data retrieved on a database, an other is used to save new data on the same database. when i navigate back to the screen that list the data (if it's already been loaded), it's not updated with the new data because the screen as already been loaded. is there a way to reload my component each time i press on one of my tab button ? Thank you in advance.

TabNavigator = createBottomTabNavigator({
        Descriptif,
        Chrono,
        Session: { screen: () => <Session myPath={this.state.myPath} /> },
        Resultats: { screen: ({ navigation }) => <Resultats navigation={navigation} myPath={this.state.myPath} /> },
        Edit: { screen: () => <Edit myPath={this.state.myPath} /> }
    }, {
            defaultNavigationOptions: ({ navigation }) => ({
                tabBarIcon: ({ tintColor }) => {
                    const { routeName } = navigation.state;
                    let IconComponent = Ionicons;
                    let iconName;
                    if (routeName === 'Descriptif') {
                        iconName = 'md-fitness';
                    } else if (routeName === 'Chrono') {
                        iconName = 'md-time';
                    } else if (routeName === 'Session') {
                        iconName = 'md-save';
                    } else if (routeName === 'Resultats') {
                        iconName = 'md-analytics';
                    } else if (routeName === 'Edit') {
                        iconName = 'md-cut';
                    }
                    return <IconComponent name={iconName} size={25} color={tintColor} />;
                },
            }),
            tabBarOptions: {
                activeTintColor: 'red',
                inactiveTintColor: 'gray',
            },
        })


class Resultats extends Component {
    constructor() {
        super()
        this.state = {
            loading: true,
            results: null
        }
    }

    focusSubscription = null;

    onWillFocus = payload => {
        console.log('didBlur', payload);
        this.readData(); // my method 
    };

    componentDidMount = () => {
        this.focusSubscription = this.props.navigation.addListener(
            'willFocus',
            this.onWillFocus
        );
    };

    componentWillUnmount = () => {
        this.focusSubscription && this.focusSubscription.remove();
        this.focusSubscription = null;
    };
}

1 Answers

Use NavigationEvents. Add event listeners to your list data component.

onWillFocus - event listener

onDidFocus - event listener

onWillBlur - event listener

onDidBlur - event listener

for example, the following will get fired when the list data screen is focused.

class App extends Component {

  focusSubscription = null;

  onWillFocus = payload => {
   // call a function to reload data here
  };

componentDidMount = () => {
  this.focusSubscription = this.props.navigation.addListener(
    'willFocus',
    this.onWillFocus
  );
};

componentWillUnmount = () => {
  this.focusSubscription && this.focusSubscription.remove();
  this.focusSubscription = null;
};

Pass navigation to your component like

Resultats: { screen: ({ navigation }) => <Resultats navigation={navigation} myPath={this.state.myPath} /> },

Or add NavigationEvents to your render in a parent view, without passing the navigation as a prop.

import {
   ...
   NavigationEvents,
 } from 'react-navigation';

class Resultats extends Component {
 ...
onWillFocus = payload => {
    console.log('didBlur', payload);
    this.readData(); // my method 
};

....
  render() {
    ...
    return (
      <View>
        <NavigationEvents
          onDidFocus={payload => this.onWillFocus(payload)}
        />
        {/* 
         Your view code
        */}
      </View>
    )
  }
Related