这是我使用 React Native 和 Expo 的第一个应用程序。 这是
"expo": "~49.0.13",
"react-native": "0.72.6",
"@react-navigation/drawer": "^6.6.5",
"@react-navigation/native": "^6.1.9",
"@react-navigation/native-stack": "^6.9.15",
我的应用程序遇到了一个非常奇怪的问题。
我有使用 useContext 创建的应用程序的全局状态。
import { UserState } from '@models/userModel';
import React, { createContext, useReducer } from 'react';
const initialState: UserState = {
isAuthenticated: false,
userData: null
};
export type TypeContext = {
state: UserState,
dispatch: React.Dispatch<any>;
};
const UserContext = createContext<TypeContext>({
state: initialState,
dispatch: () => { }
});
const { Provider } = UserContext;
type Props = {
children: any;
};
type Actions =
| {
type: 'set_user',
userData: any;
}
|{
type: 'is_authenticated',
isAuthenticated: boolean
}
| {
type: 'delete_user'
}
| {
type: 'update_user',
userData: any
};
export enum TypesInContext {
set_user = 'set_user',
is_authenticated = 'is_authenticated',
delete_user = 'delete_user',
update_user = 'update_user'
};
const reducer = (state: UserState, action: Actions): UserState =>{
switch (action.type) {
case TypesInContext.set_user:
return{
...state,
userData: action.userData,
};
case TypesInContext.is_authenticated:
console.log("ACCCCTIOOON--->",action)
return {
...state,
isAuthenticated: action.isAuthenticated
}
case TypesInContext.delete_user:
return{
...state,
userData: null,
isAuthenticated: false
}
case TypesInContext.update_user:
return {
...state,
userData: action.userData
}
default:
return state;
}
};
const UserProvider = ({children}:Props) =>{
const [state,dispatch]= useReducer(reducer,initialState);
return <Provider value={{state,dispatch}}>{children}</Provider>
};
export {UserContext,UserProvider}
我在索引中使用此状态来切换屏幕。显然,我用文档中所示的上下文包装了我的应用程序。
import { StatusBar } from 'expo-status-bar';
import Index from './src/Index';
import 'react-native-gesture-handler';
import { UserProvider } from '@src/store/userContext';
export default function App() {
return (
<UserProvider>
<StatusBar style='auto'/>
<Index />
</UserProvider>
);
}
并在这里使用
import React, { useContext } from 'react';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationContainer } from '@react-navigation/native';
import LoginScreen from '@screens/LoginScreen';
import { RootTypesNavigation } from '@navigation/typesNavigation';
import DrawerNavigation from '@navigation/DrawerNavigation';
import { UserContext } from './store/userContext';
export default function Index() {
const Stack = createNativeStackNavigator<RootTypesNavigation>();
const { state } = useContext(UserContext);
console.log("🚀 ~ file: Index.tsx:11 ~ Index ~ state:", state)
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Login'>
{state.isAuthenticated ?
<Stack.Screen name='DrawerNavigation' component={DrawerNavigation} options={{ headerShown: false }} />
:
<Stack.Screen name='Login' component={LoginScreen} options={
{ headerShown: false }
} />
}
</Stack.Navigator>
</NavigationContainer>
);
}
以及这种特殊情况下的状态,我们在这些函数中从 LoginScreen 更改它(我在这里做了一个小演示)
const submitLogin = async () => {
if (!isEmailValid(email)) {
notifyMessage('Error', "El email ingresado no es válido.")
return;
}
let objetAuthetication: ParametersLogin = {
username: email,
password: password,
domain: domain,
deviceInfo: {
available: true,
platform: Device.osName,
version: Device.osVersion,
uuid: null,
cordova: "react-native 0.72.6",
model: domain,
manufacturer: Device.brand,
isVirtual: false,
serial: null,
appVersion: "1.0.11"
}
}
const response = await authLogin(objetAuthetication);
if (response && response.status == 'OK') {
setAlertLoginOk(true);
dispatch({
type: TypesInContext.set_user,
userData: response.result,
})
} else {
alertAccessDenied();
}
}
根据业务逻辑,首先我必须进行调度来保存用户数据,然后在另一个确认中进行 isAuthenticated 的调度,在这里我更改它显示一个屏幕或另一个屏幕的状态。
const emailConfirmationAndAuthentication = async () => {
if (newEmail) {
console.log("Se registro nuevo email");
//Que hacer aca? Update? en la web no hace nada.
};
setAlertLoginOk(false);
console.log("🚀 ~ file: LoginScreen.tsx:78 ~ emailConfirmationAndAuthentication ~ navigation:", navigation)
// navigation.navigate('DrawerNavigation',{screen:'Home'})
setTimeout(()=>{
dispatch({
type: TypesInContext.is_authenticated,
isAuthenticated: true
});
},1000)
};
那个 可怕的 setTimeOut 是我的应用程序不崩溃的解决方案(感谢这个社区中的一个线程),但我真的想了解发生了什么或者发生了什么错误或者我做错了什么。
有人遇到过这个吗? 难道我做错了什么? 问题是什么? 我错过了一些文档吗?
这些问题我已经困扰好几天了,我不明白! 非常感谢!
幸运的是我能够找到问题所在。 这是 react-navigation/native-stack 库。 我改变了那个图书馆,因为 react-navigation/stack 我所有的状态问题都已经解决了。 我希望这对某人有帮助。