我试图使用上下文api和reducer进行身份验证流程, 我有一个名为GlobalState的文件,其中使用令牌保留了所有身份验证状态。我也有用reducer来更新状态。 在我的GlobalState文件中,有一个函数loginFb,它将根据我的rest API的响应来更新状态。 当我尝试控制状态时,我可以看到登录后状态已更改,但是我的应用程序未重新呈现。我期望我的应用在状态更改时重新呈现,并移至HomeStackScreens。
以下是我的app.js
import 'react-native-gesture-handler';
import React, {useContext} from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createMaterialBottomTabNavigator} from '@reactnavigation/material-bottom-tabs';
import {createStackNavigator} from '@react-navigation/stack';
import AsyncStorage from '@react-native-community/async-storage';
import HomeTabs from './screens/HomeTabs';
import Login from './screens/Login';
import {GlobalContext, GlobalProvider} from './context/GlobalState';
const AuthStack = createStackNavigator();
const HomeStack = createStackNavigator();
const AuthStackScreen = () => {
return (
<AuthStack.Navigator screenOptions={{}}>
<AuthStack.Screen name="Login" component={Login} />
</AuthStack.Navigator>
);
};
const HomeStackScreens = () => {
return (
<HomeStack.Navigator
screenOptions={{
headerTintColor: 'white',
headerStyle: {backgroundColor: '#37966f', elevation: 0},
}}>
<HomeStack.Screen name="Home" component={HomeTabs} />
</HomeStack.Navigator>
);
};
function App() {
React.useEffect(() => {
// Fetch the token from storage then navigate to our appropriate place
const bootstrapAsync = async () => {
let userToken;
console.log('is Signedin :', isSignedIn);
try {
userToken = await AsyncStorage.getItem('authTocken');
if (userToken) console.log('autTocken:' + userToken);
else console.log('no tocken');
} catch (e) {
console.log('no tocken');
}
};
bootstrapAsync();
}, []);
const {authState, isSignedIn} = useContext(GlobalContext);
return (
<GlobalProvider>
<NavigationContainer>
{console.log('from app:', authState, 'signedin', isSignedIn)}
{isSignedIn ? <HomeStackScreens /> : <AuthStackScreen />}
</NavigationContainer>
</GlobalProvider>
);
}
export default App;
Globalstate.js
import React, {createContext, useReducer} from 'react';
import AppReducer from './AppReducers';
import AsyncStorage from '@react-native-community/async-storage';
//Initial State
const initialState = {
authTocken: '',
refreshTocken: '',
fbToken: '',
isSignedIn: false,
};
export const GlobalContext = createContext(initialState);
export const GlobalProvider = ({children}) => {
const [authState, dispatch] = useReducer(AppReducer, initialState);
async function loginFb(fbToken) {
// loginFb: async fbToken=>{
await fetch(
'https://api_url?accessToken=' +
fbToken,
{
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
},
)
.then((resp) => resp.json())
.then(async function (data) {
await AsyncStorage.setItem('authTocken', data.token);
await AsyncStorage.setItem('refreshTocken', data.refreshToken);
await AsyncStorage.setItem('fbToken', fbToken);
dispatch({
type: 'SIGN_IN',
payload: data,
});
})
.catch((error) => {
console.log('found error', error);
});
}
return (
<GlobalContext.Provider
value={{authState, loginFb, isSignedIn: authState.isSignedIn}}>
{children}
</GlobalContext.Provider>
);
};
AppReducer.js
export default (state, action) => {
switch (action.type) {
case 'SIGN_IN': {
return {
...state,
isSignedIn: true,
refreshTocken: action.payload.refreshToken,
authTocken: action.payload.token,
};
}
default:
return state;
}
};
答案 0 :(得分:1)
代替
export default App;
更改为
export default () => (
<GlobalProvider>
<App />
</GlobalProvider>
)
现在可以正常使用