15

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,
    },
  }, {
   ...
}

2 Answers 2

25

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);
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Nice! But I think my question was not clear. I update user's information (props) from axios POST call. When MainPage renders componentWillMount doesn't run again (of course it was mounted before logout). Can I force to mount it once if we receive any react-navigation params (from your solution)?
The parameters you pass in navigate are available in componentWillReceiveProps and in render. You can use them there (i.e. call retrieveUser in one of them using the new token you passed)
componentWillReceiveProps() lifecycle event is now deprecated. You should use componentDidUpdate() instead: reactjs.org/docs/…
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.