React Native Redux-访问状态变量-网络版



休斯顿,我们有问题。

我一直不太了解Redux是如何工作的。到了为我的react原生应用程序进行身份验证流程的时候,我找到了一个使用reducer的教程,复制了它,它就工作了。。。我一直很困惑为什么代码能工作,因为我看不到我在";登录状态"变量插入上下文。。。但它(在ios上(工作,所以我顺其自然。

但今天,当我尝试网络版的react原生应用程序时,它成了一个问题。出于某种原因,我也不理解,声明一个不带"的变量是可以接受的;const";在react原生ios/android中,但不在web中。如果要修复我用类型声明声明redux状态的问题(如图所示(,它就不再适用于嵌套函数:

**const** [loginState, dispatch] = React.useReducer(LoginReducer, {isLoading: false, isSignout: false, userToken: null, isVerified: false})

请帮助我理解

这是我的App.js:

import * as React from 'react';
import LoginReducer from './Reducer/LoginReducer';
import AppContainer from './Navigators/AppNavigationContainer.js'
import {loadLocale, strings2} from './assets/locales/i18n'
import {AppLoading} from 'expo'
global.AuthContext = React.createContext();
global.LanguageContext = React.createContext({
language: 'es',
setLanguage:()=>{}
})
export default function App ({navigation}) {
//LanguageContext
const [languageReady, setLanguageReady] = React.useState(false);
const [language,setLanguage] = React.useState('es');

//Load language
const initLang = async () => {
const currentLanguage = await loadLocale()
setLanguage(currentLanguage)
};
[loginState, dispatch] = React.useReducer(LoginReducer, {isLoading: false, isSignout: false, userToken: null, isVerified: false})
global.authContext = React.useMemo(() => ({
signIn: () => {
dispatch({ type: 'SIGN_UP' })
dispatch({ type: 'SIGN_IN', token: 'dummy-token' });

AsyncStorage.setItem('userToken', 'dummy-token' )
},
signOut: () => {
AsyncStorage.removeItem('userToken')
dispatch({ type: 'SIGN_OUT' })
},
signUp: () => {
dispatch({ type: 'SIGN_IN', token: 'dummy-token' })
AsyncStorage.setItem('userToken', 'dummy-token')        
},
}),[]);

return(
<>
{languageReady ? (
<LanguageContext.Provider value={{language, setLanguage}}>
<AppContainer/>
</LanguageContext.Provider>

) : (
<AppLoading
startAsync={initLang()}
onFinish={setLanguageReady(true)}/>
)} 
</>
)
}

这里是我的应用导航器;登录状态"应该可以进行身份验证流。

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import LoadingScreen from '../Screens/LoadingScreen.js'
import SignInScreen from '../Screens/SignInScreen.js'
import VerifyEmail from '../Screens/VerifyEmail.js'
import MainAppTab from './MainAppTab.js'
const Stack = createStackNavigator();
export default function AppContainer () { 

return (
<AuthContext.Provider value={global.authContext}>
<NavigationContainer>
<Stack.Navigator 
initialRouteName='SignIn'
headerMode='none'
>
{loginState.isLoading ? (<> 
<Stack.Screen name='Loading' component={LoadingScreen}/>

</>) : loginState.userToken == null ? (<>
<Stack.Screen name='SignIn' component={SignInScreen}/> 
</>) : loginState.isVerified === false ? (<>
<Stack.Screen name='Verify' component={VerifyEmail}/>
</>) : (
<Stack.Screen name='Main' component={MainAppTab}/>
)}
</Stack.Navigator>
</NavigationContainer>
</AuthContext.Provider>
)
}

如果不使用constvarlet声明变量,则该变量将位于全局作用域中。这就是为什么您的状态和调度功能在任何地方都可用。未声明关键字的constvarlet都具有不同的作用域。阅读关于这个问题的JavaScript作用域、mozilla开发人员网站和w3schools的更多信息。

为了使state和dispatch函数在其他地方可用,您需要将值传递给它需要去的组件。在您的情况下,您需要把它们传递给AppContainer组件。

下面是一个例子:

App.js:

import React from 'react';
import TestAppContainer from "./TestAppContainer";
const LOGIN = "LOGIN";
// This dummy reducer just returns the current state.
// Your reducer probably does something useful :)
const TestAppReducer = (state, action) => {
switch (action.type) {
case LOGIN:
return state;
default:
return state;
}
};
export default function App() {
const [loginState, dispatch] = React.useReducer(TestAppReducer, {isLoading: false, isSignout: false, userToken: null, isVerified: false})
return (
<TestAppContainer loginState={loginState} dispatch={dispatch} />
);
}

TestAppContainer.js:

import React from "react";
import {View, Text, Button} from "react-native";
const TestAppContainer = props => {
const { loginState, dispatch } = props;
const onPressHandler = () => {
console.log(loginState);
console.log(dispatch !== undefined);
}
return (
<View style={{flex: 1, justifyContent: "center", alignItems: "center"}}>
<Text>Test App WOW!</Text>
<Button title={"Press me."} onPress={onPressHandler} />
</View>
);
}
export default TestAppContainer;

相关内容

  • 没有找到相关文章

最新更新