Trigger navigation before render

Viewed 623

I have the following code that redirects automatically to the About component when you load the FAQ component. This is done using a custom hook that uses useHistory() to push a new route to it. The custom hook also returns an empty object. When you don't try to use anything from this object, the code works perfectly and the app redirects to the About component.

But when I try to access a (non-existing) value from the object, I get the value is null error. I don't understand why the code even reaches this. Shouldn't the redirect happen before the rest of the component is rendered?

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>;
}

Why does the redirect not happen before the value is accessed? And how can I make sure that my app redirects before accessing the value?

1 Answers

Why does the redirect not happen before the value is accessed? And how can I make sure that my app redirects before accessing the value?

The redirect does happen before the value is accessed, but that does not mean that the other source code below the redirection code will not get executed. This is how it is in client side routing.

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

  return "";
}

versus if you were to perform, for example, a window.location.href server side http request redirection, the execution will depend on your internet speed

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 "";
}

I hope this clears up some potential misunderstanding of SPA redirections

Related