How do I reload a page with react-router?
Asked Answered
C

23

95

I can see in this file (https://github.com/ReactTraining/react-router/blob/v0.13.3/modules/createRouter.js) that there is a refresh function but I have no idea how to call it. I'm fairly new to react-router, I've only used it to move between some pages a couple times using hashHistory.

Right now I am trying to use it so that when an install fails, the user is given the option to 'retry' which I plan to execute by refreshing the page where the install happens (the page the user would be currently on). Any help would be appreciated.

This is a node app that runs on electron, not a web app.

Corpse answered 18/10, 2017 at 23:24 Comment(0)
P
124

firstly, add react-router as a dependency

yarn add react-router or npm install react-router

Then (for react-router v5)

import { useHistory } from 'react-router'

const history = useHistory()

// then add this to the function that is called for re-rendering
history.go(0)

This causes your page to re-render automatically

For react-router v6 use the useNavigate hook instead:

import { useNavigate } from 'react-router'

const navigate = useNavigate()

// refresh
navigate(0)
Purapurblind answered 9/4, 2020 at 14:9 Comment(4)
this works if you have a cookie being deleted in an onClick event that you handles your auth state, with history.go() i get logged out as intended and pushed to the login screen. Didn't work as intended for me with the other answers..Catt
Not really SPA approach. I think this recommendation should be criticizedAdjacency
I'm building a Web App with React and Express.js, and this suggestion worked like a charm to me. CheersPatsy
Does not work with react-router v6 (tried navigate(0)).Constantine
D
47

If you're using react-router v6

import { useNavigate } from "react-router-dom";

const navigate = useNavigate();

const refreshPage = () => {
    navigate(0);
}
Demandant answered 3/3, 2022 at 11:34 Comment(1)
I found that if you are doing this from a router as part of logout sequence then it's good to refresh your navigation to the home route first i.e. navigate("/"); navigate(0);Virgate
T
28

You can use this to refresh Current route:

import createHistory from 'history/createBrowserHistory'
const history = createHistory();
history.go(0)
They answered 13/8, 2018 at 12:19 Comment(2)
this causes full page reloadSurvivor
Something similar if you're using hooks - this works for useHistory from react-router-dom. But yes, fully page reloadNadinenadir
C
25

You don't really need react-router for this. You can just use location.reload:

location.reload();

Also that version of react-router you linked to is very old, I think it's linking to v1 when it's currently on v4.

Chris answered 18/10, 2017 at 23:47 Comment(8)
ahh makes sense. The problem with this is when it calls location.reload() it opens the file on my browser, but I am working on an electron app so it needs to reload within the app.Corpse
@Corpse Ah, try the other answer maybe. But there's also contents.reload you might want to try.Chris
Not really SPA approach. I think this recommendation should be criticizedHeredity
@SashaKos So what would be your way of solving it?Winniewinnifred
Other answers here, like history.pushState(null, '/'); are better, imhoHeredity
using this method loses any cached data (e.g. Apollo) vs using the router method.Pockmark
@SashaKos There are times where this is the approach that should be taken, such as when we deploy a new version of the SPA application and we want the maintenance mode offline component (which we are showing our users) to cause a full page refresh and fetch the new version of the SPA application (once we set the maintenance mode to off). Note that in order to solve a no-restricted-globals error (e.g. when using Create React App) with this code it should read window.location.reload().Beadledom
I'm using a SPA and this works for me, as I want to clear some cached data, as it's quite complex to remove it without really digging into my logic. I delete a record, but there are multiple records tied to it, rather refetch the data, as deleting the records is not frequent, and websocket dispatches to find and remove the items is a lot of code.Bottom
E
16

React

window.location.reload();

working

Elwandaelwee answered 9/3, 2020 at 18:31 Comment(3)
Thats can turns into a infinite loop, be carefullySalvador
How can this result in an infinite loop? Please provide some examples to reinforce your statement.Churchy
@Churchy If you place this inside a useEffect, for instance, it will trigger on the component's reload which necessarily happens every time the page loads, which will cause the page to load, etc.Clyster
H
15

I guess that you're using react-router. I'll copy my answer from another post. So you have few possibilities to do that, currently my favorite way to do that is using anonymous function in component prop:

<Switch>
  <Route exact path="/" component={()=><HomeContainer/>} />
  <Route exact path="/file/:itemPath/:refHash" component={()=><File/>} />
  <Route exact path="/:folderName" component ={()=><Folder/>}/>
</Switch>

Or if you want to refresh with current url params, you'll need extra route (reload), and play a little with router stack:

reload = ()=>{
 const current = props.location.pathname;
 this.props.history.replace(`/reload`);
    setTimeout(() => {
      this.props.history.replace(current);
    });
}

<Switch>
  <Route path="/reload" component={null} key="reload" />
  <Route exact path="/" component={HomeContainer} />
  <Route exact path="/file/:itemPath/:refHash" component={File} />
  <Route exact path="/:folderName" component ={Folder}/>
</Switch>

<div onClick={this.reload}>Reload</div>
Hallah answered 5/10, 2018 at 10:6 Comment(3)
Why is setTimeout required here?Burkley
@DawsonB I don't know but it doesn't work without it.. lolDeluxe
@DawsonB If you try to reload the page immediately, the changed route won't stick. The minimum value on a setTimeout is between 4-10ms depending on the browser, so this is effectively changing the page via URL and reloading the page with the minimum timeout. The "it doesn't work without it" is because without the delayed refresh, the 'current' isn't the new page yet.Puddling
E
14

if you want to re-fetch the data just do the below:

import { useLocation } from 'react-router'

const location = useLocation()

useEffect(() => {
  fetchData()
}, [location.key])
Enviable answered 19/8, 2021 at 12:49 Comment(2)
sweet solution!Martian
How small so smartOrnithopod
B
10

I know that this is old, but I found a simple solution according to the documentation of react-router.

Just put that attribute on your Router, and whenever you are on a new Path it will force the page to reload itself.

<Router forceRefresh={true}>

Source: https://reactrouter.com/web/api/BrowserRouter/forcerefresh-bool

Burlingame answered 15/5, 2021 at 7:26 Comment(2)
wow! no need adding key with generated uniqued id etc, this is the best solution! Terima Kasih!Calzada
This did the trick for me! Thanks so much. I am using React-Router-Dom version 5.2.0.Singlehearted
I
7

This solution won't cause the undesired full page reload but requires you to make this modification to each page that needs refreshing:

export const Page = () => {
   const location = useLocation();
   return <PageImpl key={location.key} />
}

So the idea is: create a wrapper around your page and make React re-create the actual page every time the location key changes.

Now it's enough to call history.push(/this-page-route) again and the page refreshes.

Ilo answered 10/7, 2020 at 8:29 Comment(1)
thanks for noting that histry.push(..) triggers a refreshJellybean
E
5

If you want to use <Link/> to reload some route, or simply have single history push, you can setup <Redirect/> route under <Switch/> like this:

<Switch>
    <Route exact path="/some-route" component={SomeRoute} />
    <Redirect exact from="/some-route/reload" to="/some-route" />
</Switch>

And then <Link to="/some-route/reload" /> or push("/some-route/reload")

Evesham answered 27/4, 2020 at 16:18 Comment(1)
Interesting method, worked well for my use case. Thanks!Roxie
I
5

With React Router 6 you can simply write :

import {useNavigate} from "react-router-dom";

 const navigate = useNavigate()

    const goToPageOnClick = () =>{
        navigate(target_url)
        navigate(0)
    }
Inveterate answered 31/7, 2022 at 6:12 Comment(0)
C
4

If you don't want to reload all scripts again you can replace the current path with a fake/empty path and replace it again with the current path like this

// ...
let currentPath = window.location.pathname;
history.replace('/your-empty-route');
setTimeout(() => {
    history.replace(currentPath)
}, 0)
// ...

Update:

If the changing of the address bar bothering, you can add a patterned route like this:

<Route path="/*/reload" component={null}/>

and add /replace to the end of currentPath to replace the router with null component. like this:

// ...
let currentPath = window.location.pathname;
history.replace(`${currentPath}/replace`);
setTimeout(() => {
    history.replace(currentPath)
}, 0)
// ...

In this way, the reload keyword will add to the end of your current path and I think it's more user friendly.

Notice: If you already have a route that ends with replace It will cause conflict. To solve that you should change the path of the patterned route to something else.

Crews answered 21/4, 2020 at 7:55 Comment(0)
S
3

You could try this workaround:

// I just wanted to reload a /messages page
history.pushState(null, '/');
history.pushState(null, '/messages');
Switchback answered 19/10, 2017 at 0:2 Comment(1)
For some reason, this still opens the file in my browser, but if I remove the second line and just push to the first page, it takes me there. To clarify, I'm using hashHistory.push('/somewhere')Corpse
N
2

You can use this function.

function reloadPage(){ 
    window.location.reload(); 
}
<input type="button" onClick={ reloadPage }  value="reload"/>
Nourish answered 23/10, 2020 at 17:6 Comment(0)
W
1

May be you are trying to push in history object, then bind your component with withrouter or use window.location.href = url to redirect ..

Waistcoat answered 9/7, 2019 at 20:0 Comment(0)
G
1

You can achieve that with React Router v6.

import React from 'react';
import { useNavigation, useLocation } from 'react-router-dom';

const Component = () => {
 const history = useNavigation();
 const location = useLocation();

 const reload = () => {
   navigate(location.pathname);
 };

 return (
  ...
 );
};

and then put your reload function inside a useEffect hook.

PS: but this is a weird question, since react-router reloads the page automatically.

Gunthar answered 2/10, 2022 at 11:18 Comment(0)
M
0

If you are needing an asynchronous reload, use history.go(0) (it wraps the History.go() method).

If you need to reload the page synchronously, use history.push(location.pathname) (it wraps the History.pushState() method).

Since there are already examples here using history.go(0), here's an example using history.push(location.pathname):

import React from 'react';
import { useHistory, useLocation } from 'react-router-dom';

const Component = () => {
  const history = useHistory();
  const location = useLocation();

  const reload = () => {
    history.push(location.pathname);
  };

  return (
    ...
  );
};

Melchor answered 31/8, 2021 at 18:29 Comment(1)
Please add further details to expand on your answer, such as working code or documentation citations.Tanhya
W
0

Looking at all the answers to this question they all seem to do a hard refresh of the page or worked on a specific page. I was looking to do a softer sort of refresh to the page and make a component that can do this on any page. The way I ended up implementing it was to redirect the user to a view that doesn't exist and then going back to the previous page.

using react-router-dom

import {useNavigate} from "react-router-dom";

const RefreshButton= ()=>{

    const navigate = useNavigate()

    const softRefreshPage = () =>{
        // visit page that doesn't exist
        navigate("/refresh");
        navigate(-1);
    }
    
    return <button onClick={softRefreshPage}>refresh</button>  
}

Clicking the button in this example will redirect you to the /refresh page then back. This will force the components on the current view to re render. Note a side effect of this is that the user may see a blank page for a second. You can make a page at the /refresh route that will just show a loading icon which can be more user friendly.

Winsome answered 1/9, 2023 at 21:51 Comment(0)
W
0

Here is a custom hook for reloading the page without hard refreshing and keeping search params as well :

// useReloadPage.js
export function useReloadPage() {
  const navigate = useNavigate();
  const location = useLocation();

  return () => navigate(`${location.pathname}${location.search}`);
}

In my case, I use that custom hook on tanstack's useMutation's onSuccess object :

export function useDeleteQuestion(id) {
  const queryClient = useQueryClient();
  const reload = useReloadPage();

  const { isLoading: isDeleting, mutate: deleteQuestion } = useMutation({
    mutationFn: () => deleteQuestionApi(id),
    onSuccess: () => {
      queryClient.removeQueries({
          // ...
      })
      reload();
    },
  });

  return { isDeleting, deleteQuestion };
}
Whopper answered 16/4 at 11:43 Comment(0)
G
-1

update webpacker.yml

  devServer: {
    historyApiFallback: true,
  }
Gabbro answered 23/10, 2020 at 16:46 Comment(1)
Please add an explanation to improve the insight and give the OP some more informationPforzheim
S
-1

Well, the easiest way is to first identify a route for reload and thereafter call the window.location.reload() function on the route like so:

<Switch>
  <Route exact exact path="/" component={SomeComponent} />
  <Route path="/reload" render= {(props)=>window.location.reload()} />
</Switch>
Sugary answered 2/4, 2021 at 9:49 Comment(0)
B
-1

Just Write following Code for Refresh :

window.location.reload();
Beffrey answered 28/4, 2023 at 14:0 Comment(0)
E
-2

I recently had the same problem and created this(https://github.com/skt-t1-byungi/react-router-refreshable).

<Refreshable>
    <Switch>
        <Route path="/home">
            <HomePage />
        </Route>
        <Route path="/post">
            <PostPage />
        </Route>
        {/* ... */}
    </Switch>
</Refreshable>
Endermic answered 7/8, 2021 at 2:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.