问题描述
我是本机反应的新手,我无法使此身份验证流程正常工作。我已经尝试了所有我能想到的,但它不起作用。这是我的代码
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 }
正如我在上面的代码中提到的,我从我的 graphql 服务器获取我的 User 对象是在此处获得的,并且控制台已正确记录,我在下面的 Login.js 末尾获得了令牌以及 graphql 突变中的所有其他内容
这是我的 Login.js 屏幕
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
}
}
`;
最后是我的 App.js 文件,登录后我尝试从我的 AuthContext 获取用户对象,但如果我控制台记录上下文,它会作为上面的初始上下文出现,我将在下面解释
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>
)
}
我正在使用所有软件包的最新版本
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)