Возвращение API контекста undefined не является объектом при использовании с React-Native и навигацией React - PullRequest
0 голосов
/ 16 марта 2020

Хорошо, у меня возникла эта проблема в течение двух дней, и я не могу понять, где и в чем конкретно заключается моя проблема. Я использую документацию react-navigation вместе с их процессом аутентификации в надежде построить логин / регистр / домашние экраны. Проблема, с которой я сталкиваюсь, заключается в том, что, хотя я проверил свои конечные точки API и получил действительные данные json, я не могу их отобразить и получить ошибку undefined is not an object.

AuthState . js

  import React,{useReducer} from 'react'
  import AuthContext from './authContext'
  import AuthReducer from './AuthReducer'
  import axios from 'axios';
  import {AsyncStorage} from 'react-native';
  import {LOGIN_SUCCESS, REGISTER_SUCCESS, LOGIN_FAILURE, REGISTER_FAILURE, LOGOUT, GET_USER} from 
 '../../types'

 const AuthState = props => {

const initialState = {
    authUser:null,
    loading:true,
    error:null,
    isAuthenticated:false
}

const [state, dispatch] = useReducer(AuthReducer, initialState);


const register = async(email, password, fname, lname) =>{

  const obj = {
      username:email,
      password:password,
      firstName:fname,
      lastName:lname
  }

  const config = {
      'Content-Type' : 'application/json'
  }

  try {

  const userToken = await axios.post('http://192.168.0.14:5000/api/auth/signup', obj, config);

  dispatch({type:REGISTER_SUCCESS, payload:userToken.data});

  } catch (error) {

  }

}

const login = async(email, password) =>{

  const obj = {
      username:email,
      password:password,
  }

  const config = {
      'Content-Type' : 'application/json'
  }

  try {

  const userToken = await axios.post('http://192.168.0.14:5000/api/auth/login', obj, config);

  dispatch({type:LOGIN_SUCCESS, payload:userToken.data});

  } catch (error) {

  }

}

const getUser = async() =>{

  let token = await setAuthorizatinToken();

   try {
    const res = await axios.get('http://192.168.0.14:5000/api/auth/', {
        headers:{
            'Content-Type':'application/json',
            'x-auth':token
        }
    });

    let obj = res.data;
    console.log(obj);
   dispatch({type:GET_USER, payload:obj});

   } catch (error) {

   }
}

const setAuthorizatinToken = async() =>{

    let token = await AsyncStorage.getItem('token');
   if(token){
       return token;
   } else {
      return 401;
   }
}

return (
    <AuthContext.Provider value={{
        authUser:state.authUser,
        loading:state.loading,
        error:state.error,
        register,
        login,
        getUser,
        isAuthenticated:state.isAuthenticated,
        setAuthorizatinToken
    }}>
        {props.children}
    </AuthContext.Provider>
)
}

 export default AuthState

AuthReducer. js

 import {LOGIN_SUCCESS, REGISTER_SUCCESS, LOGIN_FAILRURE,
 REGISTER_FAILURE, LOGOUT, GET_USER} from '../../types'
 import {AsyncStorage} from 'react-native';


export default async(state,action) =>{
     switch(action.type) {
    case LOGIN_SUCCESS:
    case REGISTER_SUCCESS:
    try {
        await AsyncStorage.setItem('token', action.payload);
        return {
            ...state,
            loading:false,
            isAuthenticated:true
        }
        break;
    } catch (error) {

    }
    break;
    case GET_USER:
    return{
        ...state,
        loading:false,
        isAuthenticated:true,
        authUser:action.payload
    }

    default:
        break;
   }
}

Приложение. js

return (   
  <NavigationContainer>
   <AuthState>
      <Stack.Navigator>
         <Stack.Screen name="NoToken" component={NoneStack} options={{headerShown:false}}/>            
      </Stack.Navigator>
   </AuthState>
  </NavigationContainer>
 ); 

И, наконец, экран стека

import React, {useContext, useEffect} from 'react'
import AuthContext from '../context/AuthContext/authContext';
import AuthState from '../context/AuthContext/AuthState';
import Register from '../components/Register/Register';
import Loading from '../components/Loading/Loading';
import Login from '../components/Login/Login'
import Home from '../components/Home/Home';
const None = createStackNavigator();
import {AsyncStorage} from 'react-native';

//stack navigator for tackling user authentication
const none = () => {

const authContext = useContext(AuthContext);

//check if the user has been loaded from asyncstorage
const {user, loading, getUser, isAuthenticated} = authContext;

useEffect(() => {
  //get the token if there is any and check it
  //if it's authorized, switch to home screen,
  //else, switch to login screen again
  getUser();
}, [])

 return (

     <None.Navigator>
     {/* if not, return a screen which prompts him to input his credentials */}
     {isAuthenticated == false ? (
       <>
       <None.Screen name="Register" component={Register} options={{headerShown:false}}/>
       <None.Screen name="Login" component={Login} options={{headerShown:false}}/>
       </>
     ) : (
     // if yes, return the home screen component
       <None.Screen name="Home" component={Home}/>
     )}
     </None.Navigator>
 )
}

export default none

Странно то, что после того, как я войду или создаю учетную запись, я переключаюсь на Главный экран, показывая, что состояние было обновлено, но когда дело доходит до На самом деле использовать данные в компоненте Home, упоминается выше ошибка. Любая помощь будет оценена!

...