Danil Gholtsman Danil Gholtsman - 5 months ago 19
Javascript Question

React + Redux binded state has no data it suppose to

After one of the Redux tutorials decided to implement that facny

action->reducer->store->view
chain for simple app with only login part.

Seems like all setted up but when I run my app - in
mapStateToProps(currentState)
no any sign of the any custom state fields which I expected to see! (default state from reducer). But the action function is fine, as you can see on the screenshot

enter image description here


I can't see whats wrong here so, decided to ask it.

So here is the code

So, first of all -
store.js


import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers';
import thunk from 'redux-thunk';

export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));

if (module.hot) {
module.hot.accept('../reducers', () => {
const nextRootReducer = require('../reducers');
store.replaceReducer(nextRootReducer);
});
}

return store;
}


then
login
reducer

const initialState = {
user: {
name: '',
password: ''
},
fetching: false
}

export default function login(state = initialState, action) {
switch (action.type) {
case LOGIN_REQUEST: {
return { ...state, fetching: true }
}
case LOGIN_SUCCESS: {
return { ...state, user: action.data, fetching: false }
}
case LOGIN_FAIL: {
return { ...state, user: -1, fetching: false }
}
default: {
return state;
}
}
}


and the root (
reducers/index.js
):

import login from './login/login';
import { combineReducers } from 'redux'

export default combineReducers({
login
});


the
action


import {
LOGIN_REQUEST,
LOGIN_SUCCESS,
LOGIN_FAIL
} from '../../constants/login.js';

export function onLoginAttempt(userData) {
return (dispatch) => {
dispatch({
type: LOGIN_REQUEST,
user: userData
})

tryLogin(userData);
}
};

function tryLogin(userData) {
let url = 'SignIn/Login ';

return (dispatch) => {
axios.post(url, userData)
.then((response) => dispatch({
type: LOGIN_SUCCESS,
data: response.data
})).error((response) => dispatch({
type: LOGIN_FAIL,
error: response.error
}))
}
};


So here is entrance point:

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import App from './containers/app.js';
import configureStore from './store/configureStore';

let store = createStore(configureStore);

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("content")
);


and here is the
app.js
(Login is just sompe custom div with two fields nothing special)

import React, { Component } from 'react';
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux';
import Login from '../components/login/Login';
import * as pageActions from '../actions/login/login'


class App extends Component {
render() {
const { user, fetching } = this.props;
const { onLoginAttempt } = this.props.pageActions;

return <div>
<Login name={user.name} password={user.password} fetching={fetching} onLoginAttempt={onLoginAttempt} />
</div>
}
}

function mapStateToProps(currentState) {
return {
user: currentState.user,
fetching: currentState.fetching
}
}

function mapDispatchToProps(dispatch) {
return {
pageActions: bindActionCreators(pageActions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App)

Answer Source

I see that you have state which looks like:

reduxState = {
   login: {
       user: {
         name: '',
         password: ''
       },
       fetching: false
   }
}

but then you try to access properties that don't exist.

function mapStateToProps(currentState) {
    return {
        user: currentState.user,
        fetching: currentState.fetching
    }
}

I think you need to:

function mapStateToProps(currentState) {
    return {
        user: currentState.login.user,
        fetching: currentState.login.fetching
    }
}