11

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?

1

3 Answers 3

6

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

Sign up to request clarification or add additional context in comments.

Comments

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

2 Comments

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?
@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.
1

I think by using useLayoutEffect, you can put a loader on every route change. I anyone have a question feel free to ping me.

import { useLayoutEffect, useState } from "react";
import RoutesWrapper from "./components/RoutesWrapper";
import Loader from "./components/Loader";
import { useLocation } from "react-router-dom";
function App() {
  const [loading, setLoading] = useState(true);
  const { pathname } = useLocation();
  useLayoutEffect(() => {
    setLoading(true);
    const timer = setTimeout(() => {
      setLoading(false);
    }, 2500);
    return () => clearTimeout(timer);
  }, [pathname]);
  return loading ? <Spinner /> : <RoutesWrapper />;
}

export default App;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.