Display a simple loading indicator between routes in react router

11,704

Solution 1

you can use a High Order Component in react to do this in a generic way.

Look is a example:

https://github.com/thejameskyle/react-loadable

Solution 2

If you fetching some data I made a small package react-router-loading that allows you to show loading indicator and load some data before switching the screen.

Just use Switch and Route from this package instead of react-router-dom:

import { Switch, Route } from "react-router-loading";

Add loading props to the Route where you want to wait something:

<Route path="/about" component={About} loading/>

And then somewhere at the end of fetch logic in About component add loadingContext.done();:

import { LoadingContext } from "react-router-loading";
const loadingContext = useContext(LoadingContext);

const loading = async () => {
    //loading some data

    //call method to indicate that loading is done and we are ready to switch
    loadingContext.done();
};
Share:
11,704
John
Author by

John

Updated on July 10, 2022

Comments

  • John
    John almost 2 years

    I'm coming from AngularJS world and start some days ago writing my first React App with react-router, in AngularJS I do:

    app.directive('Loading', function($rootScope, $timeout) {
        return {
            restrict: 'E',
            replace: true,
            template: '<p>Loading</p>'
            link: function(scope, element) {
                $rootScope.$on('$routeChangeStart', function(event, currentRoute, previousRoute) {
                    element.removeClass('ng-hide');
                });
    
                $rootScope.$on('$routeChangeSuccess', function() {
                    element.addClass('ng-hide');
                });
            }
        };
    });
    

    and then I just add <Loading></Loading>. So now in my React App I have:

    class App extends Component {
      render() {
        return (
           <Router>
            <div>
              <ul>
                <li><Link to="/">Home</Link></li>
                <li><Link to="/about">About</Link></li>
              </ul>
    
              <hr/>
    
              <Route exact path="/" component={Home}/>
              <Route path="/about" component={About}/>
    
            </div>
          </Router>
    
    
        );
      }
    }
    

    and my two components are simple:

    class Home extends Component {
        render() {
            return (
                <h1>Home</h1>
            );
        }
    }
    class About extends Component {
        render() {
            return (
                <h1>About</h1>
            );
        }
    }
    

    Can I do this without using reduxJS?

  • user12051965
    user12051965 almost 3 years
    I had a look on the package and I would love to use it for my project. One question, is it possible to change the position of the topbar? Right now it is on top level of screen, but I want to have it at the bottom of my header component. I am not sure if this can be achieved with topbar.config({}). Could you please tell me what can I do?
  • Victor Trusov
    Victor Trusov almost 3 years
    @user12051965 I'm using topbar (buunguyen.github.io/topbar) in my package, but it looks like where is no option to achieve it through config. Instead you can do it with css. Just add something like .topbar { top: unset !important; bottom: -12px;} to your css and adjust bottom value if necessary.