merry-go-round
merry-go-round

Reputation: 4625

How to refresh in React Navigation

Once I remove user token, user redirects to Login Page. However if I login with other user, the main page still shows the previous user information.

This is because I didn't refresh the Main page. How can I re-initialize(?) Main Page manually in react-navigation?

MainPage(Logged in as 'matt') -> Logout -> LoginPage 
-> (here I want to refresh MainPage so it can be loaded once new user login) 
-> MainPage(Should be logged in as other user 'kobe')

MainPage receive user JSON data via componentWillMount

  componentWillMount() {
    // retrieve user data 
    this.props.retrieveCurrentUser(this.props.token);
  }

Just in case you need my code...

1) This is Root navigation

const RootTabNavigator = TabNavigator ({
    Auth: {
      screen: AuthStackNavigator,
    },
    Welcome: {
      screen: WelcomeScreen,
    },
    Main: {
      screen: MainTabNavigator,
    },
  }, {

2) This is Auth Stack Navigator (Login Page)

export default StackNavigator ({
  Autho: {
    screen: AuthScreen,
  },
  SignUp: {
    screen: SignUpScreen,
  },
  SignUpBio: {
    screen: SignUpUserBioScreen,
  },
  SignUpUsername: {
    screen: SignUpUsernameScreen,
  },
}, {
    header: null,
    headerMode: 'none',
    navigationOptions: {
      header: null
    },
    lazy: true
});

3) This is Main TabNavigator

export default TabNavigator(
  {
    Feed: {
      screen: FeedScreen,
    },
    Stylebook: {
      screen: StylebookScreen,
    },
    Wardrobe: {
      screen: WardrobeScreen,
    },
    Noti: {
      screen: NotificationScreen,
    },
    Menu: {
      screen: MenuScreen,
    },
  }, {
   ...
}

Upvotes: 15

Views: 74365

Answers (2)

user56reinstatemonica8
user56reinstatemonica8

Reputation: 34134

The simplest way to manually refresh the entire current screen in React Navigation for React Native is to just replace the current screen with itself:

const refresh = () => navigation.replace(route.name, route.params)

Get navigation from the screen props or useNavigation() and get route from the screen props or useRoute.

Calling this will unmount and unload the entire current screen, re-run the navigation animation, and re-render the entire screen. Back actions and navigation history will be unchanged, and will go to the screen before this one as before the refresh.


Is refreshing the entire screen the best solution?

In most cases, probably no: this is a clunky, heavy-handed nuclear option that is very visible to the user, and unmounts and re-initialises every single hook and component. In most cases you'd be better off simply re-calling some specific data fetcher so that only the children and hooks that depend on that data get refreshed, maybe using React Native's RefreshControl component so the user can trigger it themselves by pulling down from the top.

Upvotes: 0

daramasala
daramasala

Reputation: 3030

If you use flux or redux to manage your state then you update your new state (e.g. new user name and whatever other data changes) in the store and everything gets updated.

If you don't use a state management solution then you can pass parameters in the navigate function. So when you navigate to the main page after the login, pass a flag or something that lets the main page know it needs to update.

This is the example from the linked doc:

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello, Chat App!</Text>
        <Button
          onPress={() => navigate('Chat', { user: 'Lucy' })}
          title="Chat with Lucy"
        />
      </View>
    );
  }
}

class ChatScreen extends React.Component {
  // Nav options can be defined as a function of the screen's props:
  static navigationOptions = ({ navigation }) => ({
    title: `Chat with ${navigation.state.params.user}`,
  });


  render() {
    // The screen's current route is passed in to `props.navigation.state`:
    const { params } = this.props.navigation.state;
    return (
      <View>
        <Text>Chat with {params.user}</Text>
      </View>
    );
  }
}

And in your case, when you navigate to main page:

navigate('MainPage', { token: '<new token>' })}

and in MainPage:

componentWillReceiveProps(nextProps) {
  if (nextProps.navigation.state.params.token) {
    this.props.retrieveCurrentUser(this.props.token);
  }
}

Upvotes: 25

Related Questions