How can mapStateToProps receive the updated state in react-redux implementation
<p>I'm learning react and redux implementation, and encountered a bug I cannot find a fix for.
The function <code>mapStateToProps</code> gets the initial (and empty) state.
I'm using seamless-Immutable for the state object, and I know that my reducer is in fact being called and updates the state.
I have tried every component-props related methods (<code>componentWillReceiveProps</code> , <code>componentWillMount</code> , <code>componentDidMount</code> , etc..), and
<code>mapStateToProps</code> never receives the <strong>updated</strong> state; always initial empty state. it runs before <code>this.props.dispatch</code> can be called within those methods.</p>

<p>I must be missing something...</p>

<p><strong>relevant files:</strong> </p>

<p><strong>1. app/index.js</strong>  </p>

<pre><code>import React, { Component } from 'react';
import logo from './logo.svg';
import './index.css';
import PlaylistList from '../../components/PlaylistList';
import { fetchPlaylists } from '../../store/playlists/actions';
import { getPlaylists } from '../../store/playlists/reducer';
import { connect } from 'react-redux';

class App extends Component {
  componentWillReceiveProps() {
    this.props.dispatch(fetchPlaylists();
  }
  render() {
    return (
      &lt;div className="App"&gt;
        &lt;div className="App-header"&gt;
          &lt;img src={logo} className="App-logo" alt="logo" /&gt;
          &lt;h2&gt;Welcome to My Music Store&lt;/h2&gt;
        &lt;/div&gt;
        &lt;PlaylistList playlists={this.props.playlists}&gt;&lt;/PlaylistList&gt;
      &lt;/div&gt;
    );
  }
}

function mapStateToProps(state) {
  console.dir(state); // prints the initial state (before reducer run)
  return {playlists: getPlaylists(state)}
}

export default connect(mapStateToProps)(App);
</code></pre>

<p><strong>2. actions.js:</strong>  </p>

<pre><code>import * as api from '../../services/api';
import * as types from './actionTypes';
import _keyBy from 'lodash/keyBy';

export function fetchPlaylists() {
  return async (dispatch, getState) =&gt; {
    try{
      const playlists = await api.fetchPlaylists();
      const playlistsById = _keyBy(playlists, (playlist) =&gt; playlist.id);
      dispatch( {  type: types.PLAYLISTS_FETCHED, playlistsById} );
    } catch (error) {
      console.error(error);
    }
  }
}
</code></pre>

<p><strong>3. reducer.js:</strong>  </p>

<pre><code>import * as types from './actionTypes';
import _mapKeys from 'lodash/mapKeys';
import _mapValues from 'lodash/mapValues';
import Immutable from 'seamless-immutable';

const initialState = Immutable({
    playlistsById: {},
    currentPlaylist: undefined
  }
);

export default function reduce(state = initialState, action = {}){
  switch (action.type) {
    case types.PLAYLISTS_FETCHED:
      return state.merge({
        playlistsById: action.playlistsById
      })
    default: return state

  }
}

export function getPlaylists(state) {
  let playlistsById = state.playlistsById;
  let playlistIds = _mapKeys(state.playlistsById);
  console.dir({playlistsById, playlistIds}); // prints empty objects
}
</code></pre>

<p><strong>4. reducers.js:</strong>  </p>

<pre><code>import playlistsReducer from './playlists/reducer';

export { playlistsReducer };
</code></pre>

<p><strong>5. actionTypes.js</strong>  </p>

<pre><code>export const PLAYLISTS_FETCHED = 'playlists.PLAYLISTS_FETCHED';
export const PLAYLIST_ADDED = 'playlists.PLAYLIST_ADDED';
export const PLAYLIST_REMOVED = 'playlists.PLAYLIST_REMOVED';
export const PLAYLIST_UPDATED = 'playlists.PLAYLIST_UPDATED';
export const FILTER_BY_SEARCH = 'playlists.FILTER_BY_SEARCH';
</code></pre>

<p><strong>6. src/index.js</strong>  </p>

<pre><code>import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import App from './containers/App';
import './index.css';
import * as reducers from './store/reducers';

const store = createStore(combineReducers(reducers), applyMiddleware(thunk));

ReactDOM.render(
  &lt;Provider store={store}&gt;
      &lt;App /&gt;
  &lt;/Provider&gt;,
  document.getElementById('root')
);
</code></pre>