Search code examples
reactjsreact-routerreact-hooksreact-context

Why doesn't second (sibling) React Context Provider work? Or, why doesn't a React Context Provider work if there is a sibling Context Provider above


There are routes in my react app that share data, and so I want to use Context to share data. But not all routes share the same kind of data, so my solution is to use multiple Context Providers.

<ClientsContextProvider>
  <ProtectedRoute
    exact
    path="/clients/:clientId"
    isAuth={isAuth}
    component={Client}
  />
  <ProtectedRoute
    exact
    path="/clients"
    isAuth={isAuth}
    component={Clients}
  />
</ClientsContextProvider>

<ProjectsContextProvider>
  <ProtectedRoute
    exact
    path="/projects"
    isAuth={isAuth}
    component={Projects}
  />
  <ProtectedRoute
    exact
    path="/projects/:projectId"
    isAuth={isAuth}
    component={Project}
  />
</ProjectsContextProvider>

Ultimately, the app is wrapped with an authentication context provider, but I wanted some routes to be wrapped in a specific context provider depending on the data it needs.

The current problem is that, while the routes of the top (<ClientsContextProvider>) work, but the sibling below it (<ProjectsContextProvider>) do not work. When I check the component tree with the React Developer Tools in the browser, even though I'm in the (Projects) routes, only the <ClientsContextProvider> is shown.


Solution

  • Nest the provider within the route:

    <ProtectedRoute exact path="/clients/:clientId" isAuth="{isAuth}">
      <ClientsContextProvider>
        <Clients />
      </ClientsContextProvider>
    </ProtectedRoute>
    <ProtectedRoute exact path="/clients" isAuth="{isAuth}">
      <ClientsContextProvider>
        <Clients />
      </ClientsContextProvider>
    </ProtectedRoute>
    <ProtectedRoute exact path="/projects" isAuth="{isAuth}">
      <ProjectsContextProvider>
        <Project />
      </ProjectsContextProvider>
    </ProtectedRoute>
    <ProtectedRoute exact path="/projects/:projectId" isAuth="{isAuth}">
      <ProjectsContextProvider>
        <Project />
      </ProjectsContextProvider>
    </ProtectedRoute>