Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught TypeError: store.getState is not a function

Tags:

reactjs

redux

In my redux js app (google appengine backend), I get the following warnings and error message when the page containing the Root component is opened.

Warning: Failed propType: Invalid prop store of type function supplied to Provider, expected object. Check the render method of Root. bundle.js:6169

Warning: Failed propType: Invalid prop store of type function supplied to DevToolsWrapper, expected object. Check the render method of Root. bundle.js:6169

Warning: Failed Context Types: Invalid child context store of type function supplied to Provider, expected object. Check the render method of Root. bundle.js:6169

Warning: Failed Context Types: Invalid context store of type function supplied to Connect(AsyncApp), expected object. Check the render method of Provider.

Uncaught TypeError: store.getState is not a function

This is where the error occurs in the react-redux's lib/components/createConnect.js.

    function computeStateProps(store, props) {
      var state = store.getState();  <<<<< The error occurs here.
      var stateProps = shouldUpdateStateProps ? finalMapStateToProps(state, props) : finalMapStateToProps(state);

      _invariant2['default'](_utilsIsPlainObject2['default'](stateProps), '`mapStateToProps` must return an object. Instead received %s.', stateProps);
      return stateProps;
    }

At the breakpoint, right before this error occurs, the console.log(store) returns this.

function (reducer, initialState) {
      var store = next(reducer, initialState);
      var _dispatch = store.dispatch;
      var chain = [];

      var middlewareAPI = {
        getState: store.…

However, when I run the exact same code using Node backend, console.log(store) returns this object instead.

devToolsStore: Object
dispatch: (action)
getReducer: getReducer()
getState: getState()
replaceReducer: replaceReducer(nextReducer)
subscribe: subscribe(listener)

My root component and configureStore.js looks like this:

import React, { Component } from 'react';
import { Provider } from 'react-redux';
import configureStore from '../store/configureStore';

import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import { DevTools, DebugPanel, LogMonitor } from 'redux-devtools/lib/react';


import AsyncApp from './AsyncApp';

const store = configureStore();

export default class Root extends Component {
  render() {
return (
 <div>
  <Provider store={store}>
    {() => <AsyncApp />}
  </Provider>
  <DebugPanel top right bottom>
    <DevTools store={store} monitor={LogMonitor} />
  </DebugPanel>
</div>
);
}
}

configureStore.js

import { createStore, applyMiddleware, combineReducers, compose } from "redux";
import thunkMiddleware from "redux-thunk";
import loggerMiddleware from "redux-logger";
import rootReducer from "../reducers";
import thunk from 'redux-thunk';
import { devTools, persistState } from 'redux-devtools';

const finalCreateStore = compose(
    applyMiddleware(thunkMiddleware),
    devTools(),
    persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)),
    createStore
);

export default function configureStore(initialState) {
  return finalCreateStore(rootReducer, initialState);
}
like image 483
Jason O. Avatar asked Oct 01 '15 04:10

Jason O.


1 Answers

My guess is you're running an older sample code. There was a breaking change in Redux 2.0 compose() function API.

Instead of

const finalCreateStore = compose(
    applyMiddleware(thunkMiddleware),
    devTools(),
    persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)),
    createStore
);

you probably want

const finalCreateStore = compose(
    applyMiddleware(thunkMiddleware),
    devTools(),
    persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)(createStore);
like image 184
Dan Abramov Avatar answered Sep 20 '22 00:09

Dan Abramov