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
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 theLink
component exported fromreact-router-dom
instead to instead "intercept" the navigation actions and handle all internal app routing/navigation completely client-side.Example:
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 byreact-router-dom
library, your page will not refresh and it redirect to the dashboard.For Reference of
<Link>
tag: Reference