Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reach router navigate updates URL but not component

I'm trying to get Reach Router to navigate programmatically from one of my components. The URL is updated as expected however the route is not rendered and if I look at the React developer tools I can see the original component is listed as being displayed.

If I refresh the page once at the new URL then it renders correctly.

How can I get it to render the new route?

A simplified example is shown below and I'm using @reach/[email protected] (it may also be salient that I'm using Redux).

import React from 'react';

import { navigate } from '@reach/router';

const ExampleComponent = props => {
  navigate('/a/different/url');

  return <div />;
};

export default ExampleComponent;
like image 740
Tom Avatar asked Aug 27 '19 15:08

Tom


People also ask

What does useNavigate replace do?

The useNavigate hook returns a function that lets you navigate programmatically, for example after a form is submitted. If using replace: true , the navigation will replace the current entry in the history stack instead of adding a new one.

How do you route a component?

Any component passed as a child to <Router> is called a “Route Component”. There are three types of props for Route Components. Matching Props - You provide these props where the <Router> is rendered. They are used by Router to match the component against the location to see if the component should be rendered.


2 Answers

Could it be that you use @reach/router in combination with redux-first-history? Because I had the same issue and could solve it with the following configuration of my historyContext:

import { globalHistory } from "@reach/router";
// other imports

const historyContext = createReduxHistoryContext({
   // your options...
   reachGlobalHistory: globalHistory // <-- this option is the important one that fixed my issue
}

More on this in the README of redux-first-history

like image 37
Kafkalasch Avatar answered Sep 29 '22 09:09

Kafkalasch


I was running into the same issue with a <NotFound defualt /> route component.

This would change the URL, but React itself didn't change:

import React from "react";
import { RouteComponentProps, navigate } from "@reach/router";

interface INotFoundProps extends RouteComponentProps {}

export const NotFound: React.FC<INotFoundProps> = props => {
  // For that it's worth, neither of these worked 
  // as I would have expected
  if (props.navigate !== undefined) {
    props.navigate("/");
  }
  // ...or...
  navigate("/", { replace: true });

  return null;
};

This changes the URL and renders the new route as I would expect:

...
export const NotFound: React.FC<INotFoundProps> = props => {
  React.useEffect(() => {
    navigate("/", { replace: true });
  }, []);

  return null;
};
like image 104
Kizmar Avatar answered Sep 29 '22 10:09

Kizmar