Как получить UserId и установить его как глобальную переменную, используя useContext, useState и useEffect в React-Native? - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть приложение, созданное с использованием React-Native, Amplify, AppSyn c и Cognito, и при его загрузке я хочу сохранить идентификатор пользователя и тип пользователя в качестве глобального состояния, к которому можно получить доступ на каждом экране.

Идентификатор пользователя и тип пользователя (учитель или ученик) никогда не изменятся, поскольку они создаются при регистрации.

import React, { useEffect, useState, useReducer } from 'react';
import {AppRegistry} from 'react-native';
import {name as appName} from './app.json';
import App from './src/AppNavigation';

import Amplify, { API, graphqlOperation, Auth } from 'aws-amplify';
import awsmobile from './aws-exports';

import { getUser } from './src/graphql/queries';

Amplify.configure(awsmobile);

export const UserContext = React.createContext()

function MyApp() {
  const [userContext, setUserContext] = useState({})

  const getUserIdAndType = async () => {
    try {
      // get User data
      const currentUser = await Auth.currentAuthenticatedUser();
      const userId = await currentUser.signInUserSession.accessToken.payload.sub;

      // get user data from AppSync
      const userData = await API.graphql(graphqlOperation(getUser, { id: userId }));

      setUserContext({ userId: userId, userType: userData.data.getUser.userType })

    } catch (err) {
      console.log('error', err);
  }
}

  useEffect(() => {
    getUserIdAndType()
  }, [])


  return (
    <UserContext.Provider value={userContext}>
      <App />
    </UserContext.Provider>
  );
}

AppRegistry.registerComponent(appName, () => MyApp);

Затем, когда я хочу использовать состояние контекста, я делаю следующее:

import { useContext } from 'react';
import { UserContext } from '../../../index';


function Loading ({ navigation }) {
    const userContext = useContext(UserContext)

    if (userContext.userId != '') {
        navigation.navigate('AppTabs');
    } else {
        navigation.navigate('Auth');
    }
}

export default Loading;

Или чтобы узнать, какой экран показать (Учитель или Ученик) ...

import { useContext } from 'react';
import { UserContext } from '../../../index';

function LoadingProfile ({ navigation }) {
  const userContext = useContext(UserContext)

    if (userContext.userType === 'Teacher') {
      navigation.navigate('TeacherScreen');
    } else if (userContext.userType === 'Student') {
      navigation.navigate('StudentScreen');
    }
}

export default LoadingProfile;

Когда приложение загружается, оно говорит, что userContext.userId и userContext.userType пусты, поэтому он не сохраняет состояние, когда я устанавливаю его в функции getUserIdAndType ().

-

-

-

****** Если я переписываю файл приложения (ВМЕСТО ИСПОЛЬЗОВАНИЯ КРЮЧКОВ useState, useEffect), я просто объявляю значения, тогда это работает ... поэтому я, очевидно, не правильно использую хуки или asyn c getUserIdAndType (). ******

import React, { useEffect, useState, useReducer } from 'react';
import {AppRegistry} from 'react-native';
import {name as appName} from './app.json';
import App from './src/AppNavigation';

import Amplify, { API, graphqlOperation, Auth } from 'aws-amplify';
import awsmobile from './aws-exports';

import { getUser } from './src/graphql/queries';

Amplify.configure(awsmobile);

export const UserContext = React.createContext()

function MyApp() {

   const userContext = {
     userId: '123456789', // add the user id
     userType: 'Teacher', // add the user type
   }


  return (
    <UserContext.Provider value={userContext}>
      <App />
    </UserContext.Provider>
  );
}

AppRegistry.registerComponent(appName, () => MyApp);

1 Ответ

0 голосов
/ 15 апреля 2020

измените это:

<UserContext.Provider value={{userContext}}>
  <App />
</UserContext.Provider>

на это:

<UserContext.Provider value={userContext}>
  <App />
</UserContext.Provider>

вы добавили дополнительную фигурную скобку "{"

...