zac
zac

Reputation: 4888

TypeError: Cannot read property ‘getState’ of undefined

I want to try small redux example so I installed redux but I got this error

TypeError: Cannot read property ‘getState’ of undefined

new Provider webpack-internal:///./node_modules/react-redux/es/components/Provider.js:24:25

Code:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import './index.css';

const App = () => (<div>Hi </div>);

ReactDOM.render(<Provider><App /></Provider>, document.getElementById('root'));

What is wrong ?

Upvotes: 13

Views: 52490

Answers (7)

neil
neil

Reputation: 811

I am using easy-peasy v 5.2.x

To create a store

store.js


import { createStore, action, thunk, computed } from "easy-peasy";
import api from "./api/posts"

export const store = createStore ({
    posts: [],
    setPosts: action((state, payload) => {
        state.posts = payload
    }),

})

index.js


import { StoreProvider } from 'easy-peasy'
import {store} from "./store";

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
      <StoreProvider store={store}>
        <App />
      </StoreProvider>
  </React.StrictMode>
)

Upvotes: 0

Marty McGee
Marty McGee

Reputation: 774

For me, this was because I was trying to export default store instead of export const store (despite ESLint nagging for "preferred export default" rule) -- this is similar to the answer @Sakar is mentioning.

For example: I had this, which throws the exact error message in question (WRONG):

const store = configureStore({
  reducer: {
    user,
    chat,
    email,
    invoice,
    calendar,
    permissions
  },
  middleware: getDefaultMiddleware =>
    getDefaultMiddleware({
      serializableCheck: false
    })
})
export default store

This is when I receive the error asked about here in this post. TypeError: Cannot read property ‘getState’ of undefined

So I changed it to this, and it works (it finds getState from redux) (CORRECT):

export const store = configureStore({
  reducer: {
    user,
    chat,
    email,
    invoice,
    calendar,
    permissions
  },
  middleware: getDefaultMiddleware =>
    getDefaultMiddleware({
      serializableCheck: false
    })
})

Upvotes: 2

Sakar
Sakar

Reputation: 21

I faced this error as I was not returning a function from store.js.

Wrong : export const makeStore = () =>{ configureStore({ reducer: masterReducer, }); }

Correct:

export const makeStore = () =>
      configureStore({
        reducer: masterReducer,
      }); 

Upvotes: 2

Reinier Garcia
Reinier Garcia

Reputation: 1680

That's because you also need to pass the store as a parameter to the Provider object (as a value for the prop store), which wraps the App. You could do it this way:

At index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
import {Provider} from 'react-redux';

import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import reducer from "./store/reducer";

const store = createStore(reducer);

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

registerServiceWorker();

At reducer.js:

const initialState = {
    counter: 0
}
const reducer = (state = initialState, action) => {
    return state;
}

export default reducer;

Of course, then in the reducer you need to add whatever you want to be executed, depending of the type parameter inside of the action object, which is also passed as parameter into the reducer.

An example (at index.js):

const initialState = {
    counter: 0
}

const reducer = (state = initialState, action) => {
    if (action.type === 'INC_COUNTER') {
        return {
            ...state,
            counter: state.counter + 1
        };
    }

    if (action.type === 'ADD_COUNTER') {
        return {
            ...state,
            counter: state.counter + action.value
        };
    }
}

export default reducer;

Upvotes: 1

Dax
Dax

Reputation: 1414

You can add dummy store so you can use your provider.

Provider needs store..

if you not add this u got error... TypeError: Cannot read property ‘getState’ of undefined

so add ..

const store = createStore(() => [], {}, applyMiddleware());

so u can use like this...

<Provider store={store}>
   <App />
</Provider>

Upvotes: 3

Mohannad Raslan
Mohannad Raslan

Reputation: 123

You need to add a store to your provider.

If you don't have any reducer, you can add a dummy reducer.

Assume that the dummy reducer returns an empty array.

() => []

So, your code will be changed to:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux'; 

const store = createStore(() => [], {}, applyMiddleware());

import './index.css';

const App = () => (<div>Hi </div>);

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

Upvotes: 7

Karen Grigoryan
Karen Grigoryan

Reputation: 5422

If we look inside react-redux <Provider />

<Provider /> expects to be provided a store prop:

this.state = {
  storeState: store.getState(),
                   ^^here
  store
}

Hence the error.

You can create one, though, using a reducer, should be something similar to this:

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from './reducer'
import App from './components/App'

const store = createStore(reducer)

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Upvotes: 26

Related Questions