React Router:如果不存在查询参数,则条件重定向
React Router: Conditional redirect if not query parameter present
我正在尝试进行条件重定向,如果 url 中没有 'state' 查询参数,我想重定向到错误页面。
我正尝试在我的 App.tsx 中进行。因为此时我不能使用挂钩:useLocation 或 useHistory,所以我使用以下方法获取查询参数:
export default function App(): JSX.Element {
const urlQuery = new URLSearchParams(window.location.search);
const stateParam = urlQuery.get('state');
...
}
然后:
<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>
它在工作,但是:
有没有办法对每个路由进行验证(而不是在每个屏幕文件中进行验证)?,因为有几个新页面即将到来,不需要状态参数,也错误屏幕不需要状态参数。
我想将验证保存在一个地方,可以在 App.tsx 中,也可以在另一个文件中
是的。由于您似乎正在使用 react-router-dom
v5,因此您可以创建一个自定义 Route
组件来为您执行此检查并有条件地呈现路由组件或重定向。
示例:
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" />;
};
将 StateParamRoute
用于您希望进行此检查的路由。
<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>
react-router-dom@6
更新
使用 useSearchParams
挂钩访问 queryString 搜索,并将自定义路由组件转换为包装器组件以用于布局路由。
import { Navigate, Outlet, useSearchParams } from 'react-router-dom';
const StateParamWrapper = () => {
const [search] = useSearchParams();
const stateParam = search.get('state');
return stateParam ? <Outlet /> : <Navigate to="/error?state=1" replace />;
};
...
<BrowserRouter>
<Routes>
<Route element={<StateParamWrapper />}>
<Route path="/t1" element={<T1Screen />} />
<Route path="/t4" element={<T4Screen />} />
<Route path="/t2" element={<T2Screen />} />
<Route path="/t3" element={<T3Screen />} />
</Route>
<Route path="/error" element={<ErrorScreen />} />
<Route path="/" element={<HomeScreen />} />
</Routes>
</BrowserRouter>
我正在尝试进行条件重定向,如果 url 中没有 'state' 查询参数,我想重定向到错误页面。
我正尝试在我的 App.tsx 中进行。因为此时我不能使用挂钩:useLocation 或 useHistory,所以我使用以下方法获取查询参数:
export default function App(): JSX.Element {
const urlQuery = new URLSearchParams(window.location.search);
const stateParam = urlQuery.get('state');
...
}
然后:
<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>
它在工作,但是:
有没有办法对每个路由进行验证(而不是在每个屏幕文件中进行验证)?,因为有几个新页面即将到来,不需要状态参数,也错误屏幕不需要状态参数。
我想将验证保存在一个地方,可以在 App.tsx 中,也可以在另一个文件中
是的。由于您似乎正在使用 react-router-dom
v5,因此您可以创建一个自定义 Route
组件来为您执行此检查并有条件地呈现路由组件或重定向。
示例:
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" />;
};
将 StateParamRoute
用于您希望进行此检查的路由。
<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>
react-router-dom@6
更新
使用 useSearchParams
挂钩访问 queryString 搜索,并将自定义路由组件转换为包装器组件以用于布局路由。
import { Navigate, Outlet, useSearchParams } from 'react-router-dom';
const StateParamWrapper = () => {
const [search] = useSearchParams();
const stateParam = search.get('state');
return stateParam ? <Outlet /> : <Navigate to="/error?state=1" replace />;
};
...
<BrowserRouter>
<Routes>
<Route element={<StateParamWrapper />}>
<Route path="/t1" element={<T1Screen />} />
<Route path="/t4" element={<T4Screen />} />
<Route path="/t2" element={<T2Screen />} />
<Route path="/t3" element={<T3Screen />} />
</Route>
<Route path="/error" element={<ErrorScreen />} />
<Route path="/" element={<HomeScreen />} />
</Routes>
</BrowserRouter>