Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS - Serving different contents for different URL (route paths) so it looks like a multiple page application

I'm from a Java background and new to ReactJS. So sorry if this is a dumb question, but I'be been stuck on this issue for a few days. Please help if you can.

My understanding is that react is for single-page apps. I've done some test development over the last couple of weeks and have been playing with Router etc. But I can't get my head around how you use react to create different content on different URLs. This is what I am trying to emulate:

  1. http://localhost:3000- a blank page with a Sign-in box
  2. http://localhost:3000/home - a dashboard with a menu bar across the top
  3. http://localhost:3000/about - a page with other information in but the same menu bar as 'home'

I don't want anyone to respond with details on how to create the components/layouts (I am very familiar with CSS, HTML, etc), what I don't understand is how to create a 'single-page app' with totally different content against different URLs (route paths).

If this was java, I would template the HTML and different pages would be served for different URLs. But that is server-side.

I've tried assigning a component to different routes: <Route path="/home" exact component = {Home} /> and building the content in that component but that doesn't work (I think I'm stuck in Java land and still thinking of 'serving' content).

When I look at Facebook (provider of React) it seems like all the menu actions along the top open in the same page, but I can not work out how different components can be hiding?? and appearing?? based on different routes clicked.

Maybe I've got this totally wrong and unique HTML pages are used for different routes??

Please let me know what best practice is and how I achieve this.

If you can point me to youtube videos or some simplified walk-throughs I would be very very grateful.

I've searched the web for things like "different react components on different routes", but haven't found anything that really shows how this works and what best practice is.

like image 835
Adam Davies Avatar asked Feb 06 '20 19:02

Adam Davies


2 Answers

TLDR:

You didn't get it wrong. The same HTML file is used to "serve" (or "render") different content for different routes. You probably need to double-check your component and router code, but the idea <Route path="/home" exact component={Home} /> is correct.


My long and boring answer

Some history and context:

As you mentioned, a couple of years ago, the common way to create a website was by setting up a server with some backend code that would, not only handle which HTML page should be displayed, but also what data would be displayed. Most of the operations would be done in the backend, and the frontend was only concerned about displaying data in a pleasant way.

With the advance of Javascript and its popularity, more operations started to be done in the frontend. And as the browsers become more powerful, more and more things can be done with Javascript. Sorting tables, filtering data and AJAX requests are some examples.

People started to modify the DOM (meaning that they were using Javascript, instead of a backend language, to change which data should be displayed and how they should be displayed.)

Single Page Application (IMHO):

The core idea of the Single Page Application (SPA) was to improve this process. Take ReactJS for example. The concept of it (in my own words) is:

"how can I quickly change the data that is displayed using less processing power and creating a better experience for the user?"

And the answer (also in my own words) was:

"let's only update elements on the screen that needs to be updated. Everything else will stay the same, so we don't need to re-render it."

For me, that means that a lot of applications could now use ReactJS (or Vue, Angular, etc) to be more powerful and user-friendly. But that also means that not every application should be built as a SPA. For me, there is still a lot of valid use in the "traditional" application where the backend still has a lot of control over the data.

Finally, you answer:

That said, I would say that the first thing to reflect on is, if you really need a SPA ;)

If you do, I see two ways of controlling which data should be displayed:

First, with a "Pure" conditional render:

This means a big if in your Javascript. For the sake of simplicity, here is an example:

var openMenu = "Home"

if (openMenu == "Home") {
   showHomePage()
} else if (openMenu == "About") {
   showAboutPage()
}

function showHomePage() {
   return <HomeComponent />
}

Second, with a router control

By using a react-router or things like that, you are actually "moving" your Javascript if statement to the URL, instead of a local variable 😉

Some people will disagree with this. Using URL to render specific content, may not be classified as a Single Page Application anymore since the initial idea is to control what is displayed in the screen through Javascript and not URLs.

Some people will agree, saying that different URLs will help with SEO, organization and allow users to bookmark or share links.


In the end, you just need to think about your page layout (or structure) and write that in HTML. Then, put an if statement around the parts that should change. Either like this:

<App>
    <Menu />
        {(openMenu == "Home") && <Home />}
        {(openMenu == "About") && <About />}
    <Footer />
</App>

or

<App>
    <Menu />
        <Router>
            <Route path="/home" component={Home} />
            <Route path="/about" component={About} />
        </Router>
    <Footer />
</App>

Hope that gives you a little more direction 😀

like image 86
Bruno Monteiro Avatar answered Oct 27 '22 02:10

Bruno Monteiro


I've created a sandbox for React Router example code with very minimal code. I hope that will help to understand and you can play around. As you can see, I've move Navbar outside page level components

Here is the working example https://codesandbox.io/s/react-router-dom-example-8vcqu?from-embed

Adding some code from that example

import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Switch, Route, Redirect } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contacts from "./Contacts";
import NavBar from "./Navbar";

Home() {
  return <h1>Home</h1>;
}

function About() {
  return <h1>About</h1>;
}

function Contacts() {
  return <h1>Contacts</h1>;
}

const NavBar = () => {
  return (
    <div className="navbar">
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/contacts">Contacts</Link>
        </li>
      </ul>
    </div>
  );
};


const App = () => (
  <BrowserRouter>
    <NavBar />
    <Switch>
      <Route path="/" component={Home} exact />
      <Route path="/about" component={About} exact />
      <Route path="/contacts" component={Contacts} exact />
      <Redirect to="/" />
    </Switch>
  </BrowserRouter>
);

render(<App />, document.getElementById("root"));
like image 30
Zohaib Ijaz Avatar answered Oct 27 '22 00:10

Zohaib Ijaz