Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

graphql - CreateContext not working on my react Native app with Apollo Client and graph Ql

I am new to react native and I cannot get this authentication flow to work. I have tried all I can think of but it will not work. Here is my Code

auth.js

import React, { useReducer,createContext } from 'react';
import jwtDecode from 'jwt-decode';
import AsyncStorage from '@react-native-async-storage/async-storage';

const initialState = {
    user:null
}
let token;
const getToken = async () => {
    if (token) {
      return Promise.resolve(token);
    }
  
    token = await AsyncStorage.getItem('jwtToken');
    return token;
  };


const AuthContext = createContext({
    user:null,
    login:(userData) => {},
    logout:() => {}
})

function authReducer(state, action){
    switch(action.type){
        case 'LOGIN':
            return{
                ...state,
                user:action.payload
            }
        case 'LOGOUT':{
            return{
                ...state,
                user:null
            }
        }
        default:
            return state;
    }
}

function AuthProvider(props){
    const [state,dispatch] = useReducer(authReducer, initialState);
    const login = async (userData) => {
        
        try {
            
            await AsyncStorage.setItem("jwtToken", userData.token)
           
            dispatch({
                type:'LOGIN',
                payload: userData
            })
            

        } catch(e){
            console.log(e)
        }
    }

    const logout =  async () => {
        try {
            await AsyncStorage.removeItem('jwtToken')
            dispatch({
                type:"LOGOUT"
            });

        } catch(e){
            console.log(e)
        }
    }
    console.log(state)//user object is here, but is not set in AuthContext, I cant get it from my App.js
    return (
          
            <AuthContext.Provider
                value={{ user:state.user, login, logout }}
                {...props}
            />
        
        )
}

export { AuthContext, AuthProvider, getToken }

As I mentioned in the code above, my User object from my graphql server is obtained here and is console logged correctly, I get the token along with everything else in the graphql mutation at the end of Login.js below

Here is My Login.js screen

import React,{ Component,useContext, useState } from 'react'
//import { useForm } from '../util/hooks';
import { useMutation } from '@apollo/react-hooks';
import gql from 'graphql-tag';
import { Alert, Button, FlatList, Text, TouchableHighlight, TextInput, View, StyleSheet } from 'react-native';


import { AuthContext } from '../context/auth';

function Login(props) {
    const context = useContext(AuthContext)
    const [username,setUsername] = useState('')
    const [password,setPassword] = useState('')
    const [errors, setErrors] = useState({})
    
    const [loginUser, { loading }] = useMutation(LOGIN_USER, {
        update(_, { data: { login: userData }}){cache
            context.login(userData)
            
            
        },
        onError(err){
            //error handling
        },
        variables: {username,password}
    });

    const onSubmit = () =>{
        
        loginUser();

    }

    const createTwoButtonAlert = (value) =>{
    //Alert in case of errors here also works with server side verification
    
    return (
        // JSX STUFF HERE
    )
}

const LOGIN_USER = gql`
    mutation login(
        $username:String!        
        $password:String!        
    ){
        login( 
                username:$username                
                password:$password                
            
        ) {
            id email username createdAt token
        }
    }
`;

And finally my App.js file, after logging in I try to obtain the user object from my AuthContext but if I console log the context, it comes up as the initial context from above, Ill explain below

App.js

//other imports
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import { AuthProvider } from './context/auth';
import { AuthContext } from './context/auth';
import { getToken } from './context/auth';

import Login from './components/Login';
import Register from './components/Register';
import Landing from './components/Landing';

const authLink = setContext(async (req, { headers }) => {
    const token = await getToken();
  
    return {
      ...headers,
      headers: {
        authorization: token ? `Bearer ${token}` : null,
      },
    };
  });



const httpLink = createHttpLink({
    uri: 'http://192.168.0.8:5000/graphql',

});


const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache()
});
const Stack = createStackNavigator()
export default function App() {
    
    const context = useContext(AuthContext)
    
    

    console.log(context) /// this returns the initially set context, its never changed

      
    
    
    return(
        
        <ApolloProvider client={client}>
            <AuthProvider>
                <NavigationContainer>
                    <Stack.Navigator>
                    {context.user && (
                        <Stack.Screen name="Landing" component={Landing} options={{ headerShown: false }} />
                        )}
                    {!context.user && (
                        <>
                        <Stack.Screen name="Landing" component={Landing} options={{ headerShown: false }} />
                        <Stack.Screen name="Register" component={Register} />
                        <Stack.Screen  name="Login" component={Login} />
                        </>
                        )}
                    </Stack.Navigator>
                </NavigationContainer>

            </AuthProvider>
          </ApolloProvider>
     
    )
  
}

I am using the latest versions of all packages

question from:https://stackoverflow.com/questions/65876642/createcontext-not-working-on-my-react-native-app-with-apollo-client-and-graph-ql

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...