skip to Main Content

I created a React 18 app that uses React Router 6

<body class="h-full">
<div id="root"></div>
<script src="/src/main.tsx"
        type="module"></script>
</body>
</html>

main.tsx:

const container = document.getElementById('root')
const root = createRoot(container)

root.render(
  <React.StrictMode>
    <BrowserRouter basename={'/'}>
      <Routes>
        <Route path="/" element={<Shell />} />
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
)

shell.tsx:

export const Shell = () => {
  return (
    <div className="flex min-h-full flex-col">
      <header className="shrink-0 bg-gray-900">
        <div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6 lg:px-8">
          <img
            className="h-8 w-auto"
            src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500"
            alt="Your Company"
          />
          <div className="flex items-center gap-x-8">
            <button
              type="button"
              className="-m-2.5 p-2.5 text-gray-400 hover:text-gray-300"
            >
              <span className="sr-only">View notifications</span>
              <svg
                className="h-6 w-6"
                fill="none"
                viewBox="0 0 24 24"
                strokeWidth="1.5"
                stroke="currentColor"
                aria-hidden="true"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"
                />
              </svg>
            </button>
            <a href="#" className="-m-1.5 p-1.5">
              <span className="sr-only">Your profile</span>
              <img
                className="h-8 w-8 rounded-full bg-gray-800"
                src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
                alt=""
              />
            </a>
          </div>
        </div>
      </header>

      {/*3 column wrapper */}
      <div className="mx-auto w-full max-w-7xl grow lg:flex xl:px-2">
        {/*Left sidebar & main wrapper*/}
        <div className="flex-1 xl:flex">
          <div className="border-b border-gray-200 px-4 py-6 sm:px-6 lg:pl-8 xl:w-64 xl:shrink-0 xl:border-b-0 xl:border-r xl:pl-6">
            <Menu></Menu>
          </div>

          <div className="px-4 py-6 sm:px-6 lg:pl-8 xl:flex-1 xl:pl-6">
            {/*Main area */}
          </div>
        </div>

        <div className="shrink-0 border-t border-gray-200 px-4 py-6 sm:px-6 lg:w-96 lg:border-l lg:border-t-0 lg:pr-8 xl:pr-6">
          {/*Right column area */}
        </div>
      </div>
    </div>
  )
}

menu.tsx:

export const Menu = () => {
  return (
    <div>
      {navigation.map((item) => (
        <a
          key={item.name}
          href={item.href}
          className="text-gray-600 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
        >
          {item.name}
        </a>
      ))}
    </div>
  )
}

When clicking the Dashboard menu entry, the app makes a roundtrip to the backend which reloads the entire app which is causing a flicker effect.

What am I doing wrong?

Repo with repro can be found here

2

Answers


  1. The Menu component is rendering raw anchor tags, which will make a request to the server for the linked target, e.g it reloads the page. Use the Link component exported from react-router-dom instead to instead "intercept" the navigation actions and handle all internal app routing/navigation completely client-side.

    Example:

    import { Link } from 'react-router-dom';
    
    export const Menu = () => {
      return (
        <div>
          {navigation.map((item) => (
            <Link
              key={item.name}
              to={item.href} // <-- internal paths in the App
              className="text-gray-600 .... font-medium"
            >
              {item.name}
            </Link>
          ))}
        </div>
      );
    };
    
    Login or Signup to reply.
  2. You should use <Link> tag instead of <a> tag.

    <a> tag contain the property to refresh the whole page but if you use <Link> tag which is provided by react-router-dom library, your page will not refresh and it redirect to the dashboard.

    For Reference of <Link> tag: Reference

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search