Houston, we have a problem.
I never quite understood how Redux works. When the time came to do the authentication flow for my react native app, I found a tutorial that used a reducer, copied it, and it worked... It was always very confusing to me why the code worked since I don't see where I pass in the "loginState" variable into the context... but it was working (on ios) so I let it be.
But today, as I was trying the web version of the react native app it became a problem. For some reason I dont understand either, it is acceptable to declare a variable without the "const" in react native ios/android but not web. If to fix that i declare the redux state with type declaration (like shown here) it is not available to nested functions anymore:
**const** [loginState, dispatch] = React.useReducer(LoginReducer, {isLoading: false, isSignout: false, userToken: null, isVerified: false})
Please please please help me understand
Here is my 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)}/>
      )} 
    </>
  )
}
And here is my App Navigator where the redux state "loginState" should be available to do the authentication flow.
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>
        )
}
 
    