React Router: Conditional redirect if not query parameter present
I am trying to do a conditional redirect, if there is no 'state' query parameter in the url, I want to redirect to an error page.
I am trying to do it in my App.tsx. Since at this point I can not use the hook: useLocation or useHistory, I am getting the query parameter using:
export default function App(): JSX.Element {
const urlQuery = new URLSearchParams(window.location.search);
const stateParam = urlQuery.get('state');
...
}
then:
<BrowserRouter>
{!stateParam && <Redirect to="/error?state=1" />}
<Route path="/" exact component={HomeScreen} />
<Route path="/t1" exact component={T1Screen} />
<Route path="/t4" exact component={T4Screen} />
<Route path="/t2" exact component={T2Screen} />
<Route path="/t3" exact component={T3Screen} />
<Route path="/error" exact component={ErrorScreen} />
</BrowserRouter>
It's working, but:
-
is there a way to do the verification per route (without doing it inside in each screen file)?, because there are a couple new pages coming which will not need to have state param, also error screen should not need state param.
-
I would like to keep the verification in one place, either in App.tsx or in another file
Solution 1:
Yes. Since it seems you are using react-router-dom
v5 you can create a custom Route
component that does this check for you and conditionally renders the routed component or a redirect.
Example:
import { Redirect, useLocation } from 'react-router-dom';
const StateParamRoute = props => {
const { search } = useLocation();
const urlQuery = new URLSearchParams(search);
const stateParam = urlQuery.get('state');
return stateParam ? <Route {...props} /> : <Redirect to="/error?state=1" />;
};
Use the StateParamRoute
for the routes you want this check to occur.
<BrowserRouter>
<Switch>
<StateParamRoute path="/t1" component={T1Screen} />
<StateParamRoute path="/t4" component={T4Screen} />
<StateParamRoute path="/t2" component={T2Screen} />
<StateParamRoute path="/t3" component={T3Screen} />
<Route path="/error" component={ErrorScreen} />
<Route path="/" component={HomeScreen} />
</Switch>
</BrowserRouter>