React Router 条件重定向

问题描述 投票:0回答:1

我正在使用 React、React Router 和很棒的 Reactivesearch 库构建一个搜索 UI。我正在尝试找出如何阻止用户简单地导航到 mydomain.com/search,因为这是我的搜索结果路线。

理想情况下,如果用户尝试导航到 mydomain.com/search,我将使用 RR Redirect 组件重定向到主页。

我使用

"/search"
作为 RR(v5) 中的 Route 组件渲染搜索结果页面的路线,但不太清楚如何使用
/search?q=${value}
之类的东西来渲染页面?

作为前言,我在渲染块中确实有这个(我正在使用基于类的组件来获取搜索结果)

let value = JSON.stringify(queryString.parse(location.search));
if (this.value === '' || null) {
       return (
         <Redirect to="/" />
       );
     }

但是,它不起作用...我仍然可以转到地址栏并输入 mydomain.com/search,页面就会呈现。

这是我的 SearchResults.tsx 中的一个示例:

<Route path = "/search" render={() => (
   <ReactiveList
    ...
    ...
    />
   />

我正在努力去

<Route path = `/search?q="${value}"` render={() => (
   <ReactiveList
    ...
    ...
    />
   />

更新 ReactiveList 上的文档 文档示例:

<ReactiveList
    componentId="SearchResult"
    dataField="ratings"
    pagination={false}
    paginationAt="bottom"
    pages={5}
    sortBy="desc"
    size={10}
    loader="Loading Results.."
    showResultStats={true}
    renderItem={res => <div>{res.title}</div>}
    renderResultStats={function(stats) {
        return `Showing ${stats.displayedResults} of total ${stats.numberOfResults} in ${
            stats.time
        } ms`;
    }}
    react={{
        and: ['CitySensor', 'SearchSensor'],
    }}
/>

如何阻止用户简单地导航到 mydomain.com/search ??

http-redirect react-router-dom reactivesearch
1个回答
0
投票

如果您想根据是否存在真实的

ReactiveList
查询字符串参数有条件地渲染
q
组件,那么您可以使用包装器组件、布局路由或高阶组件 (HOC) 来读取查询字符串并处理重定向逻辑。

react-router-dom@6

使用包装器

import { Navigate, useSearchParams } from 'react-router-dom';

const QuaryParametersWrapper = ({ children, parameters = [] }) => {
  const [searchParams] = useSearchParams();

  const hasParameter = parameters.some(
    (parameter) => !!searchParams.get(parameter)
  );

  return hasParameter ? children : <Navigate to="/" replace />;
};

...

<Route
  path="/search"
  element={(
    <ReactiveListWrapper parameters={["q"]}>
      <ReactiveList
        ...
        ...
      />
    </ReactiveListWrapper>
  )}
/>

使用自定义 HOC

import { Navigate, useSearchParams } from 'react-router-dom';

const withQueryParameters = (...parameters) => (Component) => (props) => {
  const [searchParams] = useSearchParams();

  const hasParameter = parameters.some(
    (parameter) => !!searchParams.get(parameter)
  );

  return hasParameter ? <Component {...props} /> : <Navigate to="/" replace />;
};

...

export default withQueryParameters("q")(ReactiveList);

...

import ReactiveListWrapper from '../path/to/ReactiveList';

...
<Route path="/search" element={<ReactiveListWrapper />} />

使用布局路线

import { Navigate, Outlet, useSearchParams } from 'react-router-dom';

const QuaryParametersLayout = ({ parameters = [] }) => {
  const [searchParams] = useSearchParams();

  const hasParameter = parameters.some(
    (parameter) => !!searchParams.get(parameter)
  );

  return hasParameter ? <Outlet /> : <Navigate to="/" replace />;
};

...

<Route element={<QuaryParametersLayout parameters={["q"]} />}>
  <Route path="/search" element={<ReactiveList />} />
</Route>

演示

Edit react-router-conditional-redirect

react-router-dom@5

v5 中不存在

useSearchParams
钩子,因此您可以创建自己的钩子。

import { useMemo } from 'react';
import { useLocation } from 'react-router-dom';

const useSearchParams = () => {
  const { search } = useLocation();
  const searchParams = useMemo(() => new URLSearchParams(search), [search]);
  return [searchParams];
};

使用包装器

import useSearchParams from '../path/to/useSearchParams';

const QuaryParametersWrapper = ({ children, parameters = [] }) => {
  const [searchParams] = useSearchParams();

  const hasParameter = parameters.some(
    (parameter) => !!searchParams.get(parameter)
  );

  return hasParameter ? children : <Redirect to="/" />;
};

...

<Route
  path="/search1"
  render={(routeProps) => (
    <QuaryParametersWrapper parameters={["q"]}>
      <ReactiveList {...routeProps} />
    </QuaryParametersWrapper>
  )}
/>

使用自定义 HOC

import { Redirect } from 'react-router-dom';
import useSearchParams from '../path/to/useSearchParams';

const withQueryParameters = (...parameters) => (Component) => (props) => {
  const [searchParams] = useSearchParams();

  const hasParameter = parameters.some(
    (parameter) => !!searchParams.get(parameter)
  );

  return hasParameter ? <Component {...props} /> : <Redirect to="/" />;
};

...

export default withQueryParameters("q")(ReactiveList);

...

import ReactiveListWrapper from '../path/to/ReactiveList';

...
<Route path="/search2" component={QueryReactiveList} />

演示

Edit react-router-conditional-redirect (RRDv5)

© www.soinside.com 2019 - 2024. All rights reserved.