33

So coming from an Angular/AngularJS background, you have states, and each state is a separate page. E.g. in a social network you can have a state with your feed, a state with a list of your friends, or a state to see a profile etc. Pretty straightforward. Not so much in React for me.

So let's say I have an application with 2 pages: a list of products and a single product view. What would be the best way to switch between them?

The simplest solution is to have an object which has a stateName and is a boolean

constructor() {
  super();

  this.state = {
    productList: true,
    productView: false
  }
}

And then have something like that in your render() function

return() {
  <div className="App">
    // Or you could use an if statement
    { this.state.productList && <ProductList /> }
    { this.state.productView && <ProductView product={this.state.product} /> }
  </div>
}

Pretty straightforward, right? Sure, for a 2 page application that is.

But what if you have a large app with 10, 20, 100 pages? The return() part of the render would be a mess, and it would be madness to track the status of every state.

I believe there should be a better way to organize your app. I tried googling around but I couldn't find anything useful (except for using if else or conditional operators).

Alexander Donets
  • 617
  • 1
  • 5
  • 13

3 Answers3

29

I'd recommend you to check react-router to solve this situation

It easily allows you to create custom routes like this:

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

const BasicExample = () => (
  <Router>
    <div>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/topics">Topics</Link>
        </li>
      </ul>

      <hr />

      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
      <Route path="/topics" component={Topics} />
    </div>
  </Router>
);

const Home = () => (
  <div>
    <h2>Home</h2>
  </div>
);

const About = () => (
  <div>
    <h2>About</h2>
  </div>
);

const Topics = ({ match }) => (
  <div>
    <h2>Topics</h2>
    <ul>
      <li>
        <Link to={`${match.url}/rendering`}>Rendering with React</Link>
      </li>
      <li>
        <Link to={`${match.url}/components`}>Components</Link>
      </li>
      <li>
        <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
      </li>
    </ul>

    <Route path={`${match.url}/:topicId`} component={Topic} />
    <Route
      exact
      path={match.url}
      render={() => <h3>Please select a topic.</h3>}
    />
  </div>
);

const Topic = ({ match }) => (
  <div>
    <h3>{match.params.topicId}</h3>
  </div>
);

export default BasicExample;

For the documentation and other examples, like nested Routing, checkout this page.

Ale Gu
  • 146
  • 9
manelescuer
  • 827
  • 1
  • 9
  • 19
6

This example uses React Router v6.

file App.js

import React from "react";
import {
 BrowserRouter as Router,
 Routes,
 Route
} from "react-router-dom";
import Products from "./pages"
import Product from "./pages/product"

const App = () => {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Products />} />
        <Route path="product" element={<Product />} />
      </Routes>
    </Router>
  );
}

export default App;

file pages/index.js

import React from "react";
import {Link} from "react-router-dom";
const Products = () => {
  return (
    <div>
      <h3>Products</h3>
      <Link to="/product" >Go to product</Link>
    </div>
  );
};
export default Products;

file pages/product.js

import React from "react";
const Product = () => {
  return (
    <div>
      <h3>Product !!!!!!</h3>
    </div>
  );
}
export default Product;
Uku Lele
  • 514
  • 1
  • 9
  • 14
  • 1
    For anyone reading in 2022, please note that `` has now changed to `` https://github.com/remix-run/react-router/blob/main/docs/getting-started/installation.md – timhc22 Feb 03 '22 at 03:18
3

The problem you have mentioned can be adressed as how to deal with routing within app. For that please take a look at available solutions such as react-router.

Another way you can tackle this problem is by moving out rendering different pages logic to component with would then render page based on data passed as props. For that you can use plain, old JavaScript object.

Andrzej Smyk
  • 1,684
  • 11
  • 21