React props not updating with store update

Viewed 36

After LOGIN_SUCCESS action, mapStateToProps is not called with the updated state. Inside Login Screen is consoled on the first run but when I do login, with the action dispatch as LOGIN_SUCCESS, the control does to the corresponding action.type. But I don't know if the store is not getting updated or the control does not get to LoginScreen

LoginScreen.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import EkoButton from '../../ui_components/EkoButton'
import { login } from '../../actions/login.actions';

class LoginScreen extends React.Component {
    constructor(props) {
        super(props)
        this.handleLogin = this.handleLogin.bind(this)
    }
    componentWillReceiveProps(nextProps) {
        console.log("Next Props ", nextProps)
    }
    handleLogin () {
        console.log("Click login")
        this.props.login("Ishan")
    }
    render() {
        console.log("Inside Home Screen")
        return (
        <View style={styles.container}>
            <EkoButton onPress={this.handleLogin}>
                <Text>Test Login</Text>
            </EkoButton>

        </View>
        );
    }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

const mapStateToProps = (state) => {
    console.log("Inside Login Screen ", state)
    const loginData = state
    return {
        loginData
    }
};

const mapDispatchToProps = dispatch => (
  bindActionCreators({
    login,
  }, dispatch)
);

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

login.reducers.js

import { combineReducers } from 'redux';
import { LOGIN_USER, LOGIN_FAILURE, LOGIN_SUCCESS } from '../types/login.types';
import { loginAction, loginSuccessAction, loginFailureAction } from '../actions/login.actions';

const INITIAL_STATE = {
  isUserAuthenticated: false,
  userProfile: null   
};

const loginReducer = (state = INITIAL_STATE, action) => {
  console.log("Dispatching action ", action.type)
  
  switch (action.type) {
    case LOGIN_USER:
      loginAction(state, action.payload)
      return state
    case LOGIN_SUCCESS: 
      return {
        ...state,
        isUserAuthenticated: true,
        userProfile: action.payload
      }
    case LOGIN_FAILURE: 
      return state
    default:
      return state
  }
};

export default loginReducer

createStore.js

import { createStore, combineReducers, applyMiddleware } from 'redux';
import loginReducer from '../reducers/login.reducers';
import apiMiddleware from '../middleware/core/api.middleware';

const rootReducer = combineReducers ({
    loginReducer
})

const middlewareEnhancer = applyMiddleware(
    apiMiddleware
)

const store = createStore(rootReducer, middlewareEnhancer);

export default store;

App.js

import "react-native-gesture-handler";
import React from "react";
import { StyleSheet } from "react-native";
import { Provider } from 'react-redux';
import store from './store/createStore';

import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import BottomBar from "./ui_containers/BottomBar/BottomBar";


const Stack = createStackNavigator();

class App extends React.Component {
  render() {
    console.log("here")
    return (
      <Provider store={store}>
        <NavigationContainer>
            <BottomBar></BottomBar>
        </NavigationContainer>
      </Provider>
      
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center"
  }
});

export default App;

login.actions.js


import { LOGIN_USER, SET_USER, REMOVE_USER, SOCIAL_SIGNOUT, ACCESS_DENIED, LOGIN_FAILURE, LOGIN_SUCCESS } from '../types/login.types';
import { API } from '../types/common.types';
import { makeServiceCall } from '../actions/common.actions' 
import store from '../store/createStore';

export const login = payload => (
    {
      type: LOGIN_USER,
      payload: payload,
    }
);

export const setUser = payload => (
  {
    type: SET_USER,
    payload: payload,
  }
);
export const removeUser = payload => (
  {
    type: REMOVE_USER,
    payload: payload,
  }
);
export const socialSignout = payload => (
  {
    type: SOCIAL_SIGNOUT,
    payload: payload,
  }
);
export const loginAgain = payload => (
  {
    type: LOGIN_USER,
    payload: payload,
  }
);

export const accessDenied = payload => (
  {
    type: ACCESS_DENIED,
    payload: payload
  }
)
export const loginSuccess = payload => (
  {
    type: LOGIN_SUCCESS,
    payload: payload
  }
)

export const loginFailure = payload => (
  {
    type: LOGIN_FAILURE,
    payload: payload
  }
)

export const loginAction = (state, data) => {
  console.log("data ", data)
  let payload = {
    url: "authentication/dummylogin/",
    method: "POST",
    data: data,
    noAuth: true,
    onSuccess: loginSuccess,
    onFailure: loginFailure,
    noClientRefId: true
  }
  store.dispatch(makeServiceCall(payload))
  
}

export const loginSuccessAction = (state, data) => {

}

export const loginFailureAction = (state, data) => {

}

common.actions.js


import { API } from '../types/common.types';

export const makeServiceCall = payload => (
    {
      type: API,
      payload: payload,
    }
);

common.reducers.js

import { combineReducers } from 'redux';

const INITIAL_STATE = {
  
};

const commonReducer = (state = INITIAL_STATE, action) => {
  console.log("State ", state)
  console.log("action ", action)
  switch (action.type) {
    default:
      return state
  }
};

export default combineReducers({
  common: commonReducer
});
2 Answers

Try doing like this

const mapStateToProps = (state) => {
    ...
    const loginData = state.login; // add it here
    return {
        loginData
    }
};

Solved it. So, I was trying to dispatch an action from the store which is incorrect. So, instead of dispatching LOGIN_USER I dispatched API and removed loginAction call from the reducer.

Related