Aleksander
Aleksander

Reputation: 61

Implementing async/await function in react-native component

I'm trying to implement a function which checks if user is authenticated before rendering the main 'App' component but I can't get my code to run AFTER the promise is resolved.

class App extends Component {
    render() {
        const sagaMiddleware = createSagaMiddleware();
        const reduxStore = createStore(reducers, {}, applyMiddleware(ReduxThunk, sagaMiddleware));
        sagaMiddleware.run(Sagas)

        getToken = async () => {
            const token = await store.get('token')
            .then( (token) => {
                if (token !== null)
                    reduxStore.dispatch({type: LOGIN_USER});
            })
            .catch( (error) => console.log(error) )
        }

        getToken();

        return (
            <Provider store={reduxStore}>
                <Router>
                    <Scene key="root">
                        <Scene key="login" component={ LoginPageContainer } hideNavBar={true}/>
                        <Scene key="feed" component={ RequireAuth(FeedPageContainer) } initial={true} hideNavBar={true}/>
                    </Scene>
                </Router>
            </Provider>
        )
    }
}

export default App;

The above code works perfectly fine except it renders the component before the getToken() function is completed. I think I may not be completely understanding how async/await works yet. Thanks in advance!

Upvotes: 2

Views: 2310

Answers (2)

Codesingh
Codesingh

Reputation: 3384

My approach of getting the stored token would be like this :

 let reduxStore 
 class App extends Component {
    render() {
        const sagaMiddleware = createSagaMiddleware();
        reduxStore = createStore(reducers, {}, applyMiddleware(ReduxThunk, sagaMiddleware));
        sagaMiddleware.run(Sagas)

        return (
            <Provider store={reduxStore}>
                <Router>
                    <Scene key="root">
                        <Scene key="login" component={ LoginPageContainer } hideNavBar={true}/>
                        <Scene key="feed" component={ RequireAuth(FeedPageContainer) } initial={true} hideNavBar={true}/>
                    </Scene>
                </Router>
            </Provider>
        )
    }

//In componentDidMount because till then your redux store will be created and you are good to go.. 

    async componentDidMount() {
        try
       {
        const token = await store.get('token')
          if(token)
          {
            reduxStore.dispatch({type: LOGIN_USER});
          }
          else
          {
            console.log('invalid token') 
          }     
       }  
        catch(error) 
        { 
          console.log(error) 
        } 

      }

    }

There are more ways to resolve the promise like one you did .then() other is callback which is an old fashion trick.

Cheers :)

Upvotes: 1

Travis White
Travis White

Reputation: 1977

A couple problems with this code. You should not do any setup in a render() function. It should purely be used for displaying current state and should not cause any side effects.

So I'd move the store creation to Constructor.

Then, you should use redux connect helper to connect the component to the store.

You can fire any setup actions in the Constructor as well, like checking to see if token exists.

I recommend redux-thunk for async actions. Dispatching an action creator allows you to getState and fire off other actions accordingly.

Upvotes: 2

Related Questions