【问题标题】:Trigger navigation before render渲染前触发导航
【发布时间】:2020-12-29 06:04:02
【问题描述】:

我有the following code that redirects automatically to the About component when you load the FAQ component。这是使用自定义钩子完成的,该钩子使用useHistory() 将新路由推送到它。自定义钩子还返回一个空对象。当您不尝试使用此对象中的任何内容时,代码会完美运行,并且应用程序会重定向到 About 组件。

但是当我尝试从对象访问(不存在的)值时,我得到了value is null 错误。我不明白为什么代码甚至达到了这一点。重定向不应该在组件的其余部分被渲染之前发生吗?

import React from "react";
import "./styles.css";

import { Link, BrowserRouter, Route, useHistory } from "react-router-dom";

export default function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Link to="/about">About</Link>
        <Link to="/faq">FAQ</Link>
        <Route path="/about" component={About} />
        <Route path="/faq" component={FAQ} />
      </BrowserRouter>
    </div>
  );
}

function useRedirect() {
  const history = useHistory();
  history.push("/about");
  return {};
}

function FAQ() {
  const { value } = useRedirect();
  return <h1>FAQ {value.name}</h1>;
}

function About() {
  return <h1>About</h1>;
}

为什么在访问value之前没有发生重定向?以及如何确保我的应用在访问 value 之前重定向?

【问题讨论】:

    标签: javascript reactjs react-router react-hooks react-router-dom


    【解决方案1】:

    为什么在访问值之前没有发生重定向?如何 我可以确保我的应用在访问该值之前重定向吗?

    重定向确实发生在值被访问之前,但这并不意味着重定向代码下面的其他源代码不会被执行。这就是它在客户端路由中的方式。

    function TestComponent() {
      const history = useHistory();
      history.push("/about");
      setTimeout(()=>{
        console.log("foo"); // <-- will get executed regardless
      }, 3000)
    
      return "";
    }
    

    如果您要执行,例如,window.location.href 服务器端 http 请求重定向,执行将取决于您的互联网速度

    function TestComponent() {
      window.location.href = "https://example.com";
      setTimeout(()=>{
        console.log("bar"); // <-- will probably not get executed - will depend on your internet speed
      }, 3000)
    
      return "";
    }
    

    我希望这能消除对 SPA 重定向的一些潜在误解

    【讨论】:

    • 很高兴知道!你知道有什么方法可以强制组件渲染之前执行导航吗?
    • 我知道防止渲染的一种方法是如果shouldComponentUpdate 返回 false。阅读this section on the "Note" area。但是,在第一次渲染时,我想您可以在推送到历史记录后立即在函数中调用 return(可以选择基于某些条件)——它技术上仍然“渲染” ,但你可以只返回(即渲染),例如,一个空字符串
    • 另外,你可能只渲染一个&lt;Redirect&gt;
    • 使用重定向是个好主意!所以我认为自定义钩子可能不应该用于重定向?
    • 我不会说它不应该用在自定义钩子中。我想有一个用例可以推广这种类型的解决方案。但是,在这种情况下,&lt;Redirect&gt; 是理想的。实际上,在您的 CodeSandBox 上(如果您首先摆脱错误),如果您继续并转到基本路径,然后单击 FAQ,然后单击浏览器后退按钮,您会注意到您不会被重定向回到基本路径 - 你会卡在/about 上。如果您使用&lt;Redirect&gt;,则不会出现这种情况
    猜你喜欢
    • 2021-09-22
    • 2020-12-21
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2018-04-05
    • 2016-07-06
    相关资源
    最近更新 更多