2

I'm making authentication in an app, and I'm kind of stuck. I have 2 different navigations. One shows if the user is logged in and another one if not. Basically, a Sign in screen. It's working fine if I change the value manually upon the start. But I can't find a way to change a state when a user signs in, for example. Even though the value in auth module changes, it doesn't update in App.js So how can I update the App.js's state from Sign in screen, for example?

import React, { Component } from 'react';
import { AppRegistry, Platform, StyleSheet, Text, View } from 'react-native';
import DrawerNavigator from './components/DrawerNavigator'
import SignedOutNavigator from './components/SignedOutNavigator'
import auth from './auth'

type Props = {};
export default class App extends Component<Props> {
  constructor(props) {
    super(props)
    this.state = {
      isLoggedIn: auth.isLoggedIn
    }
  }

  render() {
    return (
      (this.state.isLoggedIn) ? <DrawerNavigator /> : <SignedOutNavigator />
    );
  }
}

AppRegistry.registerComponent('App', () => App)

and my auth module, which is very simple import { AsyncStorage } from 'react-native'; // try to read from a local file let api_key let isLoggedIn = false

function save_user_settings(settings) {
    AsyncStorage.mergeItem('user', JSON.stringify(settings), () => {
        AsyncStorage.getItem('user', (err, result) => {
            isLoggedIn = result.isLoggedIn
            api_key = result.api_key
        });
        isLoggedIn = true
    });
}
module.exports.save_user_settings = save_user_settings
module.exports.api_key = api_key
module.exports.isLoggedIn = isLoggedIn
irondsd
  • 1,140
  • 1
  • 17
  • 34
  • What about using redux? I don't have a lot of experience using React Native, but that is the approach I would use – Jacobo Mar 04 '19 at 21:41
  • redux is huge overkill for just this problem, and it's important to know how to do it with just react. you need to create a function which modifies the state, and then pass that function down via props to any component that should trigger the state change – azium Mar 04 '19 at 21:45
  • can you show us your auth module? – azium Mar 04 '19 at 21:46
  • azium is right. I know I can solve it with Redux, but it's a big change for which I'm not ready yet. Because I need to learn React properly first – irondsd Mar 04 '19 at 21:49
  • I added auth.js to the question. I think I understand what you mean, but I don't understand how to do this yet. – irondsd Mar 04 '19 at 21:51

1 Answers1

2

First off, there are loads of ways to approach this problem. Because of this I'm going to try explain to you why what you have now isn't working.

The reason this is happening is because when you assign auth.isLoggedIn to your isLoggedIn state, you are assigning the value once, kind of as a copy. It's not a reference that is stored.

In addition to this, remember, React state is generally only updated with setState(), and that is never being called here, so your state will not update.

The way I would approach this problem without bringing in elements like Redux, which is overkill for this problem by itself, is to look into building an authentication higher order component which handles all the authentication logic and wraps your entire application. From there you can control if you should render the children, or do a redirect.

Auth Component

componentDidMount() {
 this._saveUserSettings(settings);
}

_saveUserSettings(settings) {
    AsyncStorage.mergeItem('user', JSON.stringify(settings), () => {
        AsyncStorage.getItem('user', (err, result) => {
            isLoggedIn = result.isLoggedIn
            api_key = result.api_key
        });
        this.setState({isLoggedIn: true});
    });
}

render() {
 const { isLoggedIn } = this.state;
 return isLoggedIn ? this.props.children : null;
}

App.js

render() {
   <AuthComponent>
      //the rest of authenticated app goes here
   </AuthComponent>
}

Here's a really quick, incomplete example. But it should showcase to you how you may want to lay your authentication out. You'll also want to consider error handling and such, however.

William Park
  • 1,697
  • 1
  • 12
  • 17