React Router doesn't intercept an HTTP/S request

Viewed 694

My understanding of React Router is that once the single page is bootstrapped on the client side, all subsequent calls to routes don't go to the server. They are intercepted by React Router. But why does my app always make a HTTP request to the server? Despite having the React Router code? When I see Networks on the browser dev tools, I always see a network request being made for each "react routed" route.

I tested the app by first starting the server, then delivering the index file across and then stopping the server after the client side rendering was complete. I then tried to access another route such as "/contactus" from the client side app, but the request seems to go to the server (which is now not running), and the hence the client side doesn't get any file and the browser goes blank. My understanding was that React Router intercepts all API calls once the client side bootstrapping of the app is done.

I then modified my server side code by doing a app.get("/*", function (req, res) { res.sendFile(path.join(__dirname, "../dist", "landing_page.html")); });

Now the app works. But this defeats the whole purpose of React Router as all requests are going to the server. So what is React Router then? Is it only for routing and not for interception? Is there any variant of React Router that intercepts the requests? Or do I use something like a history API? This is my code.

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
 
} from "react-router-dom";

class App extends React.Component {


  render() {
      return (
      <Router>
            <Switch>
            <Route exact path="/">
              <div className="banner">
                <Banner />
              </div>
            </Route>
          </Switch>
          <Switch>
            <Route exact path="/cloudautomation">
              <div style={{ position: "absolute", top: "15%", zIndex: "-1" }}>
                <CloudAutomation />
              </div>
            </Route>
          </Switch>
          <Switch>
            <Route exact path="/marketingautomation">
              <div style={{ position: "absolute", top: "15%", zIndex: "-1" }}>
                <MarketingAutomation />
              </div>
            </Route>
          </Switch>
          <Switch>
            <Route exact path="/contactus">
              <div style={{ width: "100%" }}>
                <ContactUs />
              </div>
            </Route>
          </Switch>
        </div>
        </Router>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("main"));
2 Answers

React-router-dom is usually used to prevent your page from reloading every asset when routing through your own website, hence, providing that SPA experience.

If you are looking to intercept requests, you can use axios.

Example from their own docs:

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  }, function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    return Promise.reject(error);
  });

Somewhat correct.

React-router will "intercept", so to speak, any calls and subsequently perform the client side routing. There wouldn't be a server call for every request. However, certain scenarios will trigger a call to the server and that (usually) results in the server responding with the index.js file for all (usually) the paths requested. An example is if you manually refresh the page. And in your example, you appear to be doing so in that you don't seem to be using "Links" but instead typing in the paths in the address bar.

If you add the below;

<Link to='/'>Banner</Link>
<Link to='/cloudautomation'>Cloud Automation</Link>
<Link to='/marketingautomation'>Marketing automation</Link>
<Link to='/contactus'>Contact us </Link>

between Router and Switch at the beginning, you will notice that there aren't any server calls triggered. You can also use a single Switch component for all the routes.

Related