Redux connect no puede llegar a la tienda

Estoy desarrollando un reactrio aplicación redux. Este es mi app.js:

import 'react-native-gesture-handler';
import React from 'react';
import {Provider} from 'react-redux';
import AsyncStorage from '@react-native-community/async-storage';

import {DefaultTheme, Provider as PaperProvider} from 'react-native-paper';

import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';  

import AppHeader from './components/ui/AppHeader';
import Home from './views/Home';
import Login from './views/Login';
import MyCoupons from './views/MyCoupons';
import ShoppingCart from './views/ShoppingCart';
import Signup from './views/Signup';
import Intro from './views/Intro';

import reducers from './reducers/index';
import configureStore from './store';

export const store = configureStore(reducers);

const Tab = createBottomTabNavigator();

const App = () => {
  let localStorageUser = null;

  const getLocalStorageUser = async () => {
    try {
      localStorageUser = await AsyncStorage.getItem('user');
    } catch (error) {
      console.log(error);
    }
  };


  const getInitialRouteName = () => {
    switch(localStorageUser) {
      case null: return 'Cuenta'
      case '': return 'Cuenta'
      default: return 'Home'
    }
  }

  return (
    <>
      
      
        
            
               ({
                  tabBarIcon: ({focused, color, size}) => {
                    let iconName;

                    if (route.name == 'Home') {
                      iconName = focused? 'home': 'home-outline';
                    } else if (route.name == 'Mis Cupones') {
                      iconName = focused? 'film': 'film-outline';
                    } else if (route.name == 'Carrito') {
                      iconName = focused? 'cart': 'cart-outline';
                    } else if (route.name == 'Cuenta') {
                      iconName = focused? 'person-circle': 'person-circle-outline';
                    }

                    return 
                  }
                })}
              >
                
                
                
                
              
            
          
      
    
  );
};

export default App;

Este es mi store/index.js:

import {applyMiddleware, compose, createStore} from 'redux';
import reducers from '../reducers/index';
import {routerMiddleware} from 'connected-react-router';
import createSagaMiddleware from 'redux-saga';
import rootSaga from '../sagas/index';

import {Provider} from 'react-redux';
import AsyncStorage from '@react-native-community/async-storage';

const sagaMiddleware = createSagaMiddleware();

const middlewares = [sagaMiddleware];
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;


export default function configureStore(initialState) {
  const store = createStore(initialState,
    composeEnhancers(applyMiddleware(...middlewares)));

  sagaMiddleware.run(rootSaga);

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers/index', () => {
      const nextRootReducer = require('../reducers/index');
      store.replaceReducer(nextRootReducer);
    });
  }
  return store;
}

Este es mi reducers/index.js:

import {combineReducers} from 'redux';

import Auth from './Auth';

export default () => combineReducers({
  auth: Auth,
});

Este es mi reducers/Auth.js:

import {
  GET_USER_SUCCESS,
  LOGIN_SUCCESS,
  SET_USER,
} from '../types';

const INIT_STATE = {
  username: null,
  token: null,
  userInfo: null,
};

export default (state = INIT_STATE, action) => {
  switch (action.type) {
    case LOGIN_SUCCESS: {
      return {
        ...state,
        username: action.payload.username,
        token: action.payload.token
      }
    }
    case GET_USER_SUCCESS: {
      return {
        ...state,
        userInfo: Object.assign({}, action.payload.userInfo)
      }
    }
    case SET_USER: {
      return {
        ...state,
        username: null,
        token: null,
        userInfo: null,
      }
    }
    default:
      return state
  }
}

Y esto es views/Login.js, donde intento conectarme a la tienda:

import React from 'react';
import {View, StyleSheet} from 'react-native';
import {Button, TextInput, Headline} from 'react-native-paper';
import globalStyles from '../styles/global';

import {connect} from 'react-redux';
import AsyncStorage from '@react-native-community/async-storage';

import {login} from '../actions/Auth';

class Login extends React.Component {
  constructor (props) {
    super();

    this.state = {
      email: '',
      password: '',
      loggedIn: false
    };
  }

  render () {
    const setLocalStorageUser = async (user) => {
      try {
        await AsyncStorage.setItem('user', user);
      } catch (error) {
        console.log(error);
      }
    };
  
    const handleNewUserPress = () => {
      navigation.navigate('Signup');
    }
  
    const handleLoginPress = async () => {
      login(this.state.email, this.state.password);
  
      navigation.navigate('Home');
    }

    const handleChange = (name, text) => {
      this.setState({[name]: value});
    }

    return (
      
         handleChange('email', text)} />
         handleChange('password', text)} />
        
        
      
    );
  }
}

const styles = StyleSheet.create({
  input: {
    marginBottom: 20,
    backgroundColor: 'darkgray'
  },
  button: {
    color: 'white',
    backgroundColor: 'blue',
    marginBottom: 20
  }
})

const mapStateToProps = ({auth}) => {
  const {username, token} = auth;
  
  return {username, token};
}

const mapDispatchToProps = {
  login,
}

export default connect(mapStateToProps, mapDispatchToProps)(Login);

El problema es que este acuerdo está elevando esta exceptio:

enter image description here

He comprobado el código varias veces y no he podido encontrar mi error.

Pregunta hecha hace 3 años, 4 meses, 26 días - Por geekglitcher


3 Respuestas:

  • Su problema está aquí:

    export default () => combineReducers({
      auth: Auth,
    });
    

    ahora tu reducers usted suministra a createStore es un function ... no los productores combinados

    Esto debería ser

       export default combineReducers({
          auth: Auth,
        });
    

    Respondida el Dec 19, 2020 a las 06:31 - por daniel1

    Votos positivos: 0 | Votos negativos: 0

  • El error que estás experimentando se debe a la forma incorrecta en la que estás utilizando el connect de Redux en tu componente Login.js. El problema radica en que estás importando e intentando conectarte al store de Redux directamente en el componente, pero el store no puede ser accesible directamente desde un componente de React.

    Para solucionar este problema, te recomendaría realizar los siguientes ajustes:

    • En tu componente `Login.js`, asegúrate de importar el store directamente desde `app.js`, donde se define y se pasa como propiedad a la aplicación utilizando `Provider`.
    • Elimina la importación de `Provider` y `connect` en `Login.js`, moviendo estas importaciones a `app.js` donde se declara el componente `Provider`.

    Aquí tienes una guía paso a paso para corregir el código:

    • En `app.js`:
    1. Elimina la importación de `Provider` de `react-redux` del archivo `Login.js`.
    • En `Login.js`:
    1. Elimina la importación de `Provider` y `connect` de `react-redux`.
    • En el método `handleLoginPress`, en lugar de llamar directamente a `login(email, password)`, puedes acceder a la función `login` a través de `this.props` ya que se pasa como una acción mapeada (`mapDispatchToProps`).
    • Debes asegurarte de que `navigation` esté disponible en el componente. Si estás utilizando React Navigation, debes asegurarte de que se encuentre en el stack de navegación de tu aplicación.

    Con estos ajustes, deberías poder corregir el error y permitir que el componente Login pueda comunicarse adecuadamente con el store de Redux a través de las acciones definidas. ¡Espero que esta guía te sea de ayuda! ¡Déjame saber si tienes alguna otra pregunta!

    Respondida el Dec 20, 2020 a las 06:32 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema es que estás intentando utilizar el gancho useDispatch fuera de un componente React. El gancho useDispatch solo se puede utilizar dentro de un componente funcional de React.

    Para solucionar este problema, puedes envolver tu componente Login en un componente funcional de React de la siguiente manera:

    javascript
    import React, { useEffect } from 'react';
    import { useDispatch } from 'react-redux';
    
    const LoginWrapper = (props) => {
      const dispatch = useDispatch();
    
      useEffect(() => {
        dispatch(login(email, password));
      }, [email, password]);
    
      return ;
    };
    
    export default LoginWrapper;
    

    Luego, puedes conectar el componente LoginWrapper a la tienda Redux de la siguiente manera:

    javascript
    const mapStateToProps = ({ auth }) => {
      const { username, token } = auth;
    
      return { username, token };
    };
    
    const mapDispatchToProps = {
      login,
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(LoginWrapper);
    

    Respondida el Dec 20, 2020 a las 06:39 - por Gemini

    Votos positivos: 0 | Votos negativos: 0