reactjsreact-routerreact-router-v4react-componentreact-router-component

Is it possible to abstract the Link declarations when using React-Router?


Consider the following:

import { Route, Link, Switch } from "react-router-dom";
import { Redirect } from 'react-router'

function Index() {
  return <h2>Home</h2>;
}

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

function Users() {
  return <h2>Users</h2>;
}

function NotFound() {
  return <h2>Not found</h2>;
}

function App() {
  return(
    <div>
      <h1>Welcome to Next.js!</h1>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about/">About</Link>
          </li>
          <li>
            <Link to="/users/">Users</Link>
          </li>
          <li>
            <Link to="/people/">People</Link>
          </li>
        </ul>
      </nav>

      <Switch>
        <Route path="/" exact component={Index} />
        <Route path="/about/" component={About} />
        <Route path="/users/" component={Users} />
        <Redirect from="/people/" to="/users/" />
        <Route component={NotFound}/>
      </Switch>
    </div>
  );
}

export default App;

Is there anything that prevents one from doing this?

import { Route, Switch } from "react-router-dom";
import LinkNav from './LinkNav'
import { Redirect } from 'react-router'

function Index() {
  return <h2>Home</h2>;
}

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

function Users() {
  return <h2>Users</h2>;
}

function NotFound() {
  return <h2>Not found</h2>;
}

function App() {
  return(
    <div>
      <h1>Welcome to Next.js!</h1>
      <nav>
        <LinkNav/>
      </nav>

      <Switch>
        <Route path="/" exact component={Index} />
        <Route path="/about/" component={About} />
        <Route path="/users/" component={Users} />
        <Redirect from="/people/" to="/users/" />
        <Route component={NotFound}/>
      </Switch>
    </div>
  );
}

Are there any drawbacks?


Solution

  • You may use import { Route, Switch, Redirect } from 'react-router-dom'
    instead of import { Redirect } from 'react-router',

    as 'react-router-dom' is a wrapper on top of 'react-router' and you are already used 'react-router-dom' in your codebase

    You have created a component but it's not fully data driven (if you required to). You may refactor your code to feed your LinkNav

    App.js

    function App() {
      const navBars = [
        { name: "Home", path: "/" },
        { name: "About", path: "/about" },
        { name: "Users", path: "/users" },
        { name: "People", path: "/people" }
      ];
      return (
        <div>
          <h1>welcome</h1>
          <nav>
            <LinkNav data={navBars} />
          </nav>
          <Switch>
            <Route path="/" exact component={Index} />
            <Route path="/about/" component={About} />
            <Route path="/users/" component={Users} />
            <Redirect from="/people/" to="/users/" />
            <Route component={NotFound} />
          </Switch>
        </div>
      );
    }
    

    linkNav.jsx

    import React from "react";
    import { Link } from "react-router-dom";
    const LinkNav = ({ data }) => {
      return (
        <ul>
          {data.map(nav => (
            <li key={nav.path}>
              <Link to={nav.path}>{nav.name}</Link>
            </li>
          ))}
        </ul>
      );
    };
    
    export default LinkNav;