React Native, Redux can't find context

Viewed 112

I'm new to redux and trying to grasp the concept of it. I'm receiving the error when redux is looking for context value. I'm sure that I wrapped the whole application in the Provider but still don't understand why it still results in the following error:

Error: could not find react-redux context value; please ensure the component is wrapped in a Provider

This is my themeReducer.js file:

const initialState = {
    theme: "dark",
}

const themeReducer = (state = initialState, action) => {
    if (action.type === "changeTheme"){
        if (state.theme === "dark"){
            return {theme: "light"};
        } else {
            return {theme: "dark"}
        }
    }
    return state
}

export default themeReducer

This is my index.js for the store:

import {createStore, combineReducers} from 'redux';
import themeReducer from './reducers/themeReducer'

const rootReducer = combineReducers({
    theme: themeReducer
})

const store = createStore(rootReducer)

export default store

Lastly, this is where I wrapped the root component with the provider to access the state:

import "react-native-gesture-handler";
import React from "react";
import { ThemeProvider } from "styled-components";
import AppNavContainer from "./src/navigations/index";
import { Provider } from "react-redux";
import { useSelector } from "react-redux";
import store from "./src/store/index"


export default function App() {
  const currentTheme = useSelector(state => state.theme)
  return (
    <Provider store={store}>
      <ThemeProvider theme={{ mode: {currentTheme} }}>
        <AppNavContainer />
      </ThemeProvider>
    </Provider>
  );
}

I'm using the styled component to access the theme value to change the background colour of my custom components. How I understand redux is that if I wrap everything under the Provider, I can access that state anywhere underneath that Provider. Did I do something wrong? Any opinions are appreciated

1 Answers
return (
    <Provider store={store}>
      <ThemeProvider theme={{ mode: {currentTheme} }}>
        <AppNavContainer />
      </ThemeProvider>
    </Provider>
  );

The store (and thus useSelector) is only available to components that are farther down the component tree from the Provider. So in ThemeProvider, in AppNavContainer, and anything inside AppNavContainer. You cannot use useSelector in App, because there is no Provider farther up the tree from App.

You'll probably want to split this component into multiple components. For example:

export default function App() {
  return (
    <Provider store={store}>
      <ThemeWrapper />
    </Provider>
  );
}

function ThemeWrapper () {
  const currentTheme = useSelector(state => state.theme)
  return (
    <ThemeProvider theme={{ mode: {currentTheme} }}>
      <AppNavContainer />
    </ThemeProvider>
  );
}
Related