Reputation: 134
I want to be able to pass some contexts only for some pages, but the way react-router is made I can't find out how to do that. For example, I want to AlertsProvider to be available only to alerts screen, GroupsProvider to be available only for groups screen and so on
How can I do this?
Here is the code I have right now:
<React.StrictMode>
<GlobalStyle />
<BrowserRouter>
<AuthProvider>
<PropertiesProvider>
<BuyersProvider>
<AlertsProvider>
<GroupsProvider>
<Switch>
<PrivateRoute path="/" exact component={Dashboard} />
<Route path="/login" exact component={Login} />
<Route path="/recover_password" exact component={RecoverPassword} />
<PrivateRoute path="/imoveis" exact component={Properties} />
<PrivateRoute path="/compradores" exact component={Buyers} />
<PrivateRoute path="/grupos" exact component={Groups} />
<PrivateRoute path="/alertas" exact component={Alerts} />
<PrivateRoute path="/relatorios" exact component={Reports} />
</Switch>
</GroupsProvider>
</AlertsProvider>
</BuyersProvider>
</PropertiesProvider>
</AuthProvider>
</BrowserRouter>
</React.StrictMode>
Upvotes: 2
Views: 1420
Reputation: 6637
Why can't you just add the relevant providers around their corresponding route components? e.g. -
<Switch>
<PrivateRoute path="/alertas" exact>
<AlertsProvider>
<Alerts />
</AlertsProvider>
</PrivateRoute>
</Switch>
Edit: After you comment clarifying that some routes need to share a context - I guess another approach you could use is to just separate them out into multiple Switch
statements - you don't need to have everything in one. Obviously I don't know all your particular use cases but you could do something like this -
<BrowserRouter>
<AuthProvider>
<PropertiesProvider>
<Switch>
<Route path="/" exact component={Dashboard} />
<PrivateRoute path="/imoveis" exact component={Properties} />
</Switch>
</PropertiesProvider>
<AlertsProvider>
<Switch>
<PrivateRoute path="/alertas" exact component={Alerts} />
<PrivateRoute path="/relatorios" exact component={Reports} />
</Switch>
</AlertsProvider>
</AuthProvider>
</BrowserRouter>
The downside to this approach is that you're still rendering the PropertiesProvider
and AlertsProvider
even if you don't actually need them (though this does solve your issue of not making them available to child components that shouldn't have access to them). You can solve this with a bit more plumbing, though -
<BrowserRouter>
<AuthProvider>
<Switch>
<Route exact path={["/", "/imoveis"]}>
<PropertiesProvider>
<Route exact path="/" component={Dashboard} />
<PrivateRoute path="/imoveis" component={Properties} />
</PropertiesProvider>
</Route>
<Route exact path={["/alertas", "/relatorios"]}>
<AlertsProvider>
<PrivateRoute path="/alertas" component={Alerts} />
<PrivateRoute path="/relatorios" component={Reports} />
</AlertsProvider>
</Route>
</Switch>
</AuthProvider>
</BrowserRouter>
Upvotes: 5