useDispatch() Error: Could not find react-redux context value; please ensure the component is wrapped in a <Provider>

ReactjsReact NativeReduxReact Redux

Reactjs Problem Overview


I am trygin to use React-Redux library and I am getting the error on the title. I wrapped my components with Provider but I still get the error, only if I implement the useDispatch() hook.

The app worked fine, until I added the useDispatch() line. The rest of lines regarding the dispatch function can be removed and I still get the same error.

If you could help me I would really appreciate it. Thanks

Here is my code:

import 'react-native-gesture-handler';
import {NavigationContainer} from '@react-navigation/native';
import Navigator from './navigation/Navigator';

import React, {useEffect, useState, useCallback} from 'react';
import {SafeAreaView, StyleSheet, Text, View} from 'react-native';

import {createStore, combineReducers} from 'redux';
import {Provider, useDispatch} from 'react-redux';
import dataReducer from './store/reducers/dataReducer';
import {CONSTANTS} from './constants/constants';
import {saveInitialData} from './store/actions/dataActions';

const App = () => {
  const [fetched, setFetched] = useState(initialState);

  const dispatch = useDispatch();

  const saveInitialDataHandler = useCallback(data => {
    dispatch(saveInitialData(data));
    callback;
  }, []);

  const rootReducer = combineReducers({
    content: dataReducer,
  });

  const store = createStore(rootReducer);

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = () => {
    fetch(CONSTANTS.database)
      .then(response => response.json())
      .then(responseJSON => {
        setFetched(true);
        saveInitialDataHandler(responseJSON);
      });
  };

  if (!fetched) {
    return (
      <Provider store={store}>
        <View stlye={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
          <Text></Text>
        </View>
      </Provider>
    );
  } else {
    return (
      <Provider store={store}>
        <NavigationContainer>
          <SafeAreaView style={styles.SafeAreaView}>
            <Navigator></Navigator>
          </SafeAreaView>
        </NavigationContainer>
      </Provider>
    );
  }
};

const styles = StyleSheet.create({
  SafeAreaView: {flex: 1},
});

export default App;

Reactjs Solutions


Solution 1 - Reactjs

App must be wrapped in provider since you are using useDispatch in it. Right now it's just a child. Provider sets the context so only its children can have access to it, not a parent.

One solution would be to create a wrapper component for it:

const AppWrapper = () => {
  const store = createStore(rootReducer);

  return (
    <Provider store={store}> // Set context
      <App /> // Now App has access to context
    </Provider>
  )
}

const App = () => {
  const dispatch = useDispatch(); // Works!
...

Solution 2 - Reactjs

maybe you imported Provider into the App.js file. Provider needs to be imported into the file index.js.

/*index.js*/
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './store/reduxStore';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

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

Solution 3 - Reactjs

If you get this error when run npm run test Then issues is related your test file.

Update or replace your app.test.tsx by below code

NB: Don't forget to install redux-mock-store if you don't have already.

import React from 'react';
import { render } from '@testing-library/react';

import App from './App';

import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';

describe('With React Testing Library', () => {
    const initialState = { output: 10 };
    const mockStore = configureStore();
    let store;

    it('Shows "Hello world!"', () => {
        store = mockStore(initialState);
        const { getByText } = render(
            <Provider store={store}>
                <App />
            </Provider>
        );

        expect(getByText('Hello World!')).not.toBeNull();
    });
});

I got this solution after searching 1 hours. Thanks a lot to OSTE

Original Solution: Github issues/8145 and solution link


With this solution if you get error like TypeError: window.matchMedia is not a function then solve by this way. add those line to your setupTests.ts file. Original solution link stackoverflow.com/a/64872224/5404861

global.matchMedia = global.matchMedia || function () {
  return {
    addListener: jest.fn(),
    removeListener: jest.fn(),
  };
};

Solution 4 - Reactjs

I did this on the same index.js file for a react-native app. This way you avoid having to export and add another file just for giving wrapping the App with the provider.

const ReduxProvider = () => {
	return(
		<Provider store={store}>
			<App />
		</Provider>
	)
}

AppRegistry.registerComponent(appName, () => ReduxProvider);

Solution 5 - Reactjs

Happened to me, when I was calling React component as a function, without using it as virtual dom, Comp was independently called not rendered as child of some element

function Comp() {
  const a = useSelector(selectA); // throws error
}
Comp();

so in my case solution was to call Comp and a component, not as a function i.e <Comp />

Solution 6 - Reactjs

import store from "../redux/Store";

store?.dispatch(actions.setSocket({ socket }));

first save the action. Then use dispatch with that store if the component is not saved in Provider.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMIPBView Question on Stackoverflow
Solution 1 - ReactjsBrian ThompsonView Answer on Stackoverflow
Solution 2 - ReactjsMatteo ZappalàView Answer on Stackoverflow
Solution 3 - ReactjsMD AshikView Answer on Stackoverflow
Solution 4 - ReactjsPixele9View Answer on Stackoverflow
Solution 5 - ReactjsAkshay Vijay JainView Answer on Stackoverflow
Solution 6 - ReactjsSehrish WaheedView Answer on Stackoverflow