reactjs 手动刷新或输入URL后,React Router重定向到其他组件

vbopmzt1  于 2023-03-12  发布在  React
关注(0)|答案(1)|浏览(167)

我在单击表中的一行后打开了一个模态。当用户单击该行时,也会反映在URL中。但当用户在模态打开时刷新页面时,用户应被重定向到另一个在全页中显示模态内容的组件。

<Route path="/payments-list" element={<Payments searchParams={searchParams} navigate={navigate} />} />
<Route path="/payments-list/:id" element={<Payments searchParams={searchParams} navigate={navigate} />} />
<Route path="/payments-list/:id" element={<PaymentWrapper />} />

const PaymentWrapper = () => {
  const { id } = useParams();
  return <PaymentDetail paymentId={id} fullPage={true} onClose={() => console.log} />;
};

这些是路径。2基本上,如果用户点击〈Payments组件中的一行,它将打开支付细节模态。3但是如果用户刷新页面,应该被重定向到PaymentWrapper组件。4简而言之,我想在Reddit中实现post显示逻辑。

lnxxn5zx

lnxxn5zx1#

实现这一点的方法是通过历史状态。用户访问的链接需要注入一些历史状态,表明它们来自应用内部。这种情况下历史状态的好处是,如果它们来自外部,它将不存在。刷新有点复杂,但我们会谈到这一点。
首先,同一个路由上只能有一个组件,因此URL只需要一个<Route>,但随后您将能够根据它们是来自应用还是来自该单一路由内的外部来分支。为了便于举例,我将使用PaymentsWrapper。因此,删除第一个/payments-list/:id路由并保留第二个:

<Route path="/payments-list/:id" element={<PaymentWrapper />} />

现在,无论您在何处导航到此URL(从您的代码看,您似乎正在使用navigate()调用),请将其更改为在历史状态中放置一个标志。fromApp并不特殊,它只是我们创建的一些内容,用于指示它们来自应用内部。state可以包含任何内容。

navigate('/payments-list/1234', {state: { fromApp: true }}})

如果使用<Link>,则可以通过state属性执行此操作。
现在,在PaymentWrapper中,您可以使用标志执行任何需要的操作:

const PaymentWrapper = () => {
  const { id } = useParams();
  const { state: { fromApp } } = useLocation();

  if (fromApp) {
    return // Whatever you need here for what is shown when navigating from inside the app
  }

  return // Whatever you need here for what is shown when refreshing or navigating from the outside
};

刷新时push状态会持续,所以如果你需要在刷新时切换模式,你可以在一个像<App>这样的高级组件中添加一个效果--在你的路由器上面的某个地方。

const navigate = useNavigate()
useEffect(() => {
   navigate(window.location.href, {replace: true, state: { fromApp: false }})      
}, [])

由于触发此效果的唯一方法是硬刷新(只要它在应用中处于高位),因此它将清除标记。此处的replace确保不会在每次刷新时添加额外的历史记录项。

相关问题