80

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.

Austin Greco
  • 32,997
  • 6
  • 55
  • 59
Sheriff
  • 937
  • 1
  • 7
  • 10

22 Answers22

110

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)
Bart
  • 2,062
  • 15
  • 19
sambalicious
  • 1,302
  • 1
  • 6
  • 8
  • 1
    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.. – Lucas Reppe Welander Jun 08 '20 at 09:10
  • 5
    Not really SPA approach. I think this recommendation should be criticized – Ott Oct 31 '21 at 18:43
  • 1
    I'm building a Web App with React and Express.js, and this suggestion worked like a charm to me. Cheers – Giovanni Pizzato Nov 17 '21 at 12:30
  • 1
    Does not work with react-router v6 (tried `navigate(0)`). – Andrey Jul 29 '22 at 08:26
38

If you're using react-router v6

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

const navigate = useNavigate();

const refreshPage = () => {
    navigate(0);
}
Dako Junior
  • 587
  • 6
  • 8
  • 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); – bownie Jan 30 '23 at 08:25
27

You can use this to refresh Current route:

import createHistory from 'history/createBrowserHistory'
const history = createHistory();
history.go(0)
vahdet
  • 6,357
  • 9
  • 51
  • 106
Sumit Kumar
  • 763
  • 9
  • 14
24

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.

Austin Greco
  • 32,997
  • 6
  • 55
  • 59
  • 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. – Sheriff Oct 18 '17 at 23:58
  • @Sheriff Ah, try the other answer maybe. But there's also [`contents.reload`](https://electron.atom.io/docs/api/web-contents/#contentsreload) you might want to try. – Austin Greco Oct 19 '17 at 00:08
  • 76
    Not really SPA approach. I think this recommendation should be criticized – Sasha Kos Sep 04 '19 at 11:53
  • @SashaKos So what would be your way of solving it? – Arup Rakshit Dec 30 '19 at 10:28
  • 3
    Other answers here, like history.pushState(null, '/'); are better, imho – Sasha Kos Jan 02 '20 at 12:02
  • 1
    using this method loses any cached data (e.g. Apollo) vs using the router method. – Wil Wells Jul 22 '20 at 17:13
  • 6
    @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()`. – shlgug Nov 24 '20 at 13:05
  • 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. – RJA Mar 03 '23 at 20:22
14

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>
Alp
  • 29,274
  • 27
  • 120
  • 198
Darko Pranjic
  • 371
  • 3
  • 7
  • 3
    Why is `setTimeout` required here? – Dawson B Aug 29 '19 at 18:34
  • 1
    @DawsonB I don't know but it doesn't work without it.. lol – Newoda Sep 30 '20 at 16:57
  • @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. – ATLUS May 23 '23 at 12:03
12

React

window.location.reload();

working

ahmetsadri
  • 177
  • 1
  • 6
  • 14
    Thats can turns into a infinite loop, be carefully – Desarrollalab Oct 14 '20 at 07:10
  • How can this result in an infinite loop? Please provide some examples to reinforce your statement. – Jan Jan 21 '22 at 21:11
  • @Jan 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. – tinkoh Feb 02 '22 at 21:46
12

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

import { useLocation } from 'react-router'

const location = useLocation()

useEffect(() => {
  fetchData()
}, [location.key])
SaimumIslam27
  • 971
  • 1
  • 8
  • 14
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

adevinwild
  • 278
  • 4
  • 8
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.

Monsignor
  • 2,671
  • 1
  • 36
  • 34
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")

GintV
  • 51
  • 1
  • 3
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.

Behnam Azimi
  • 2,260
  • 3
  • 34
  • 52
3

You could try this workaround:

// I just wanted to reload a /messages page
history.pushState(null, '/');
history.pushState(null, '/messages');
Alessander França
  • 2,697
  • 2
  • 29
  • 52
  • 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')` – Sheriff Oct 19 '17 at 16:57
3

With React Router 6 you can simply write :

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

 const navigate = useNavigate()

    const goToPageOnClick = () =>{
        navigate(target_url)
        navigate(0)
    }
Sayok Majumder
  • 1,012
  • 13
  • 28
2

You can use this function.

function reloadPage(){ 
    window.location.reload(); 
}
<input type="button" onClick={ reloadPage }  value="reload"/>
Hasip Timurtas
  • 983
  • 2
  • 11
  • 20
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 ..

Navnath Adsul
  • 364
  • 3
  • 10
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.

uki
  • 47
  • 3
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 (
    ...
  );
};

aubundy
  • 13
  • 5
  • 2
    Please add further details to expand on your answer, such as working code or documentation citations. – Community Aug 31 '21 at 20:22
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.

user14665310
  • 524
  • 4
  • 13
-1

update webpacker.yml

  devServer: {
    historyApiFallback: true,
  }
-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>
Kevin Kiwango
  • 111
  • 1
  • 4
-1

Just Write following Code for Refresh :

window.location.reload();
-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>
byungi
  • 1