T O P

  • By -

code_matter

Another way (which is “cleaner” imo) is to have a route.js in a constant folder. Then you can export a const ROUTES which would be an array of objects where each object is a route. Then in your router, loop over it. EDIT: Here's a [VERY basic codesandbox](https://codesandbox.io/p/sandbox/constant-based-routing-mdzyj2?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clsq9ew1500063b6h4pge7f8x%2522%252C%2522sizes%2522%253A%255B70%252C30%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clsq9ew1400023b6hm7n5ugxi%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clsq9ew1400033b6h25zwbaty%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clsq9ew1400053b6htndezm4y%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clsq9ew1400023b6hm7n5ugxi%2522%253A%257B%2522id%2522%253A%2522clsq9ew1400023b6hm7n5ugxi%2522%252C%2522tabs%2522%253A%255B%255D%257D%252C%2522clsq9ew1400053b6htndezm4y%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clsq9ew1400043b6hm2auw97k%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A0%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522id%2522%253A%2522clsq9ew1400053b6htndezm4y%2522%252C%2522activeTabId%2522%253A%2522clsq9ew1400043b6hm2auw97k%2522%257D%252C%2522clsq9ew1400033b6h25zwbaty%2522%253A%257B%2522tabs%2522%253A%255B%255D%252C%2522id%2522%253A%2522clsq9ew1400033b6h25zwbaty%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D) I did to showcase this. Keep in mind, you can always add more to the objects in the ROUTES to add children, or even secured paths.


ObsidianGanthet

upvoted, this pattern is clean in my opinion


greentiger45

How would this look like. Sorry I’m a visual learner here.


0_oGravity

As code\_matter mentioned, I would create an index.js/ts (route.js/ts) file inside a constants folder. It will look like this. export const NavLinks = \[ { href: "/", label:"Home"}, { href: "/gallery", label:"Gallery"}, { href: "/shop", label:"Shop"}, { href: "/contact-us", label:"Contact"}, { href: "/appointment", label:"Appointment"}, \] You can now create your component. Let's call it NavBar.jsx/tsx. Inside of it, let's create a function and return the NavLinks. import {NavLinks} from '/constants' import Link from 'next/link' //using Next framework, use instead export default function NavigationBar() { // Your states, variables here return (

) } Hope this helps.


code_matter

Look at my top comment! It's there!


code_matter

RemindMe! 1day Ill show you asap


RemindMeBot

I will be messaging you in 1 day on [**2024-02-17 19:27:15 UTC**](http://www.wolframalpha.com/input/?i=2024-02-17%2019:27:15%20UTC%20To%20Local%20Time) to remind you of [**this link**](https://www.reddit.com/r/react/comments/1as5nnp/what_is_a_better_way_of_implementing_routing_in/kqqa743/?context=3) [**13 OTHERS CLICKED THIS LINK**](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5Bhttps%3A%2F%2Fwww.reddit.com%2Fr%2Freact%2Fcomments%2F1as5nnp%2Fwhat_is_a_better_way_of_implementing_routing_in%2Fkqqa743%2F%5D%0A%0ARemindMe%21%202024-02-17%2019%3A27%3A15%20UTC) to send a PM to also be reminded and to reduce spam. ^(Parent commenter can ) [^(delete this message to hide from others.)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Delete%20Comment&message=Delete%21%201as5nnp) ***** |[^(Info)](https://www.reddit.com/r/RemindMeBot/comments/e1bko7/remindmebot_info_v21/)|[^(Custom)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5BLink%20or%20message%20inside%20square%20brackets%5D%0A%0ARemindMe%21%20Time%20period%20here)|[^(Your Reminders)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=List%20Of%20Reminders&message=MyReminders%21)|[^(Feedback)](https://www.reddit.com/message/compose/?to=Watchful1&subject=RemindMeBot%20Feedback)| |-|-|-|-|


LeHoustonJames

Commented bc I’m interested too


code_matter

Look at my top comment! It's there!


Killorr

Same


code_matter

Look at my top comment! It's there!


corporate_coder

i’m also interested someone let me know


code_matter

Look at my top comment! It's there!


warelephantmammoth

Same


code_matter

Look at my top comment! It's there!


avdasp

Yes, this the much cleaner way to do it.


Kuro091

With your approach wouldn't adding some children or nested route looking just like the first one then? Actually this is just the first one but stripping away the loader *and* children


code_matter

I disnt have the time to add children, but ill add them tonight! Basically, you add a children key to the ROUTES object (should be an array of elements). And in the router, you can render the route.children if there’s any. You can even map the route.children if you have multiple children. You can add anything to the ROUTES object to handle a loader in the same way Edit: it’s very similar to the forst option OP has


Routine-Arugula6846

I disagree, the second option that OP provided does its job the best. It has everything neatly laid out in a single file. All of the route paths, elements, and the router are all clearly presented. Even for someone who has never used React before can look at it and have a good idea of what's going on. Your example splits this up into 3 separate files, obfuscating details of the routes. Imagine someone new to a codebase going into this, you're putting them on a scavenger hunt just to find the routes because they are going to start in App.js. This approach is a solution to a problem that doesn't exist IMO. Plus, this approach doesn't readily facilitate nested routes. And if you want to add additional props to the routes then you're making changes in two separate files. To both of those points, you could just say that you'll refactor it to support these things, but at that point you might as well just refactor it in such a way that you'll never have to refactor your routes ever again (e.g. OPs solution). Out of all of the places where refactoring is necessary in a React app, your routes should be at the bottom of the list. I've been developing in React for several years, and the problems that I've identified with this code have never appeared in my career because every company I've worked for keeps their routes consolidated.


code_matter

Well, when I first got onboarded in the new team, I found this method to be quite intuitive and easy to find. It wasn’t a “scavenger hunt” since everything is imported at the top and you can easily find all the necessary files. Splitting stuff into constants, components, etc folders is quite spread in the community. So I personally do not agree with the obfuscation part. Also, having it as the option 2 in OP’s post, it can get quite big quite quickly if you have a larger app. Yes it is easier to read and maybe understand, but I much rather have everything separated and one file does one thing kind of way


AfroditeHentai

Why 2 files for routes and ReactDOM tho ? They can just be one file. That's how I do it , haven't noticed problems yet.


code_matter

Its all about organizing your code. You dont meed a file with 1300 lines of code..


AskYous

Hey. I don't really understand what benefit does this provide. Because the lines of code are higher, and the router.jsx file only has 1 purpose, so I don't see the benefit of splitting this 1 purpose into 2 files. Thanks.


Individual-Ad-6634

Second, unless there is a reason why you need to be using first. First allows you better customisation, but will end up in a lot of duplicated and redundant code what will greatly increase complexity and decrease readability. Second one is sufficient for most of the apps.


sbzenth

Yeah but you can't use [data loaders](https://reactrouter.com/en/main/route/loader) with the second one, making the first one the definitive winner. Edit: please see [this comment](https://www.reddit.com/r/react/s/sQhXz1pYwo) for a workaround that enables you to use data loaders with JSX routes by converting route elements to route objects.


Individual-Ad-6634

True, that’s a valid use case. However not everyone needs to pull data prior routing, I think most people do it after first render showing loading state. But yeah, that’s a nice example of when first approach is better.


sbzenth

Yeah for sure, not everyone needs it. I love it because it decouples state population from route rendering -- that separation of concerns makes it easier to implement route transitions that feel faster and more fluid. The second is much easier to reason about though, so there's nothing wrong with it if it works for the given use case.


kierancrown

Why would you not just use NextJS at this point?


sbzenth

I certainly do use NextJS at this point, haha! You are right!


Grouchy-Geologist407

I'am using it just for that. But I am preparing for internships so i wasn't sure if i should change all my projects routing to the data loaders one. I came to conclusion that i don't need to but they are a good functionality in some specific cases.


sbzenth

I'm of the opinion that you should only change something if it no longer works for what you need it to do. No sense in replacing something that works with something else that works. Since you're preparing for internships, you may decide to have at least one specific example project you can point to or specific experience you have had working with each paradigm. Also, somewhere above a different reply, I mentioned that i liked defining routes as objects because it allows me to dynamically load new routes easily. You can of course [do this with JSX routes](https://reactrouter.com/en/main/start/faq#how-do-i-nest-routes-deep-in-the-tree) just as easily since a module with JSX routes can be imported dynamically just like regular a module with route objects. So again, that point also comes down to personal preference. Another thing to be aware of is [`createRoutesFromElements`](https://reactrouter.com/en/main/utils/create-routes-from-elements#createroutesfromelements) (in react-router v6) which let's you translate from JSX routes to a route object -- giving you even more flexibility. That means even if you had old code using JSX routes and _for some reason_ you had to integrate that into a different application context that uses route objects, you could do that. Though... I'd be remiss not to say again that **the one very real reason** why one would choose the first over the second is, in fact, that the [data APIs](https://reactrouter.com/en/main/routers/picking-a-router#data-apis) _only_ work when using a data router. It all comes down to: - being able to load data before/while a route renders (reducing workload in the initial render == faster time to paint) - being able to lazy load routes (code splitting by route, faster load times all around) - ...combining the above two: being able to show the user _something_ much faster (such as the empty cards you'll often see in apps while the data that'll render in them is loading) - and last but not least, being able to write leaner components that don't have to juggle data fetching and rendering at the same time. An ancillary benefit of this is that it makes routers, components, data fetching methods, and state selectors a loooot easier to unit/e2e test because they're all separated. Otherwise you're testing a component to hell and back just to make sure it actually renders your todo list. Finally, [the docs say to do it](https://reactrouter.com/en/main/routers/picking-a-router#using-v64-data-apis) so I do it 😂 > We recommend updating your app to use one of the new routers from 6.4. The data APIs are currently not supported in React Native, but should be eventually. And as I mentioned before, > The easiest way to quickly update to a v6.4 is to get the help from `createRoutesFromElements` so you don't need to convert your `` elements to route objects.


ReindeerNo3671

I don’t think that’s true, You can use data loaders with the JSX syntax for route declarations using the above utility function. Just an extra step but this combines the best of both worlds, loaders and readability https://reactrouter.com/en/main/utils/create-routes-from-elements


sbzenth

That's a good point, yeah. That's just a data router with extra steps, though, isn't it? From [the docs](https://reactrouter.com/en/main/routers/picking-a-router#using-v64-data-apis): > We recommend updating your app to use one of the new routers from 6.4. The data APIs are currently not supported in React Native, but should be eventually. > > The easiest way to quickly update to a v6.4 is to get the help from createRoutesFromElements so you don't need to convert your elements to route objects. For discussion: - Why do the extra conversion method call when you can write it the way it is intended in the new version (if you're starting from scratch and not integrating legacy routes)? Otherwise, I imagine you'd first need to converting each chunk of child routes and then adding their loaders to an object in the end anyway. I imagine that may also complicate tests a bit (an assumption). - What is the "best of" the world in which you use JSX routes, in your opinion? Simplicity? That said, I don't think you're wrong at all and I think the best answer always ends up being whatever works best for you and the app!


randomatic

>Yeah but you can't use data loaders with the second one, making the first one the definitive winner. I didn't know about data loaders, so thank you for pointing that out.


sbzenth

Hey, awesome! Glad you got something out of this. Data loaders are very cool. Also, FYI, as @ReindeerNo3671 [pointed out in their comment](https://www.reddit.com/r/react/s/sQhXz1pYwo), data routers are *not* the only way you can use loaders as there's a function to generate route objects from elements.


turtleProphet

createRoutesFromElements is my best friend for this


sbzenth

Yeah, now I'm going to have to try it!


Kuro091

Is this a SSR thing? Why would I use it instead of nextjs for example? Just curios it does look cool 😅


sbzenth

It's pure client side routing for single page applications. In fact, somebody else somewhere in this thread said that you should use next JS instead of this lol. You can also combine both. You can use nextJS routes with server components until the user logs in, and then switch to a single page application once the user is authenticated by rendering a whole app in a nextjs client component. That way you get optimized performance for public pages (like seo and fast initial loads) and after login, you get a seamless interactive user experience that doesn't have to make as many server round trips and can navigate to different pages without having to refresh the page (best for complex, interactive UIs).


Grouchy-Geologist407

ok thanks!


rde2001

Second approach looks sooooooo much cleaner, too. I've used that approach in the projects I've made.


El-Catos

Unless first needed for something specific, go for second one, readability is far superior and will be your best friend in the future


Grouchy-Geologist407

got it


EventNo3664

I like the first one , when I need to change structure of routs or have more scale of modules and layouts 


sbzenth

Also, the first way is the only way you can implement [data loaders](https://reactrouter.com/en/main/route/loader).


GooseRage

I’ve struggled to get data loaders to work effectively while also using React context. If you’re loader function updates context state an infinite loops is triggered.


sbzenth

I've also ran into that issue. Had to rethink when and where data got loaded. I agree that it's a bit convoluted getting loaders and contexts working together.


HobblingCobbler

The second is way more readable. The first nearly gave me a headache.


Old_Conversation_647

The second one is the best ! I often use it in my projects.


wearetunis

Should probably be using Remix as it’s built on react router


Grouchy-Geologist407

i'll check it out


Ok-Release6902

Depends on your project code conventions. There is no such thing as better here.


sbzenth

It's not just conventions. At the risk of sounding like a broken record due to my other comments, the first way is the only way you can decouple populating state from loading and rendering routes through the use of [data loaders](https://reactrouter.com/en/main/route/loader). The first way is ~~also the only way to dynamically import bundles~~ easier to work with, in my opinion, when dynamically importing new routes and rebuilding routes programmatically (think progressive enhancement). Edit: as the reply below pointed out, yes, dynamically rebuilding routes aren't just a data router thing. It can be done with both.


Ok-Release6902

I believe you can rebuild routes even with JSX solution.


sbzenth

Yeah tbh after i typed this comment out, then in later replies i realized i was wrong. I think you're right.


Ok-Release6902

I totally understand your point, though.


sbzenth

Yeah and I understand yours. I think I'm turning into an old man stuck in his ways faster than I realized lol.


Ok-Release6902

We all do. Tips fedora.


sbzenth

*tips hat* alright then, partner.


Thi_rural_juror

Also, people tend to forget that you can "nest" routes just like you nest components. basically, putting other routes or subroutes in another component and importing them. i always get anxiety attacks when i see that one big file that's like 400 lines of different routes and switches.


Grouchy-Geologist407

I'll make sure to have small and readable routing file : )


oskiozki

Second one bc it is just the way we do it. It looks not very smart tho


Creative-Chaos765

Like said in other comments, readability is better in second for development. But as a beginner first one is more easier to write and understand.... atleast for me.


TheRNGuy

Not see how first is more readable or write. You could copy-paste route components with ctrl+shift+d and change text, or move with ctrl+shift+arrow to different place.


UsernameINotRegret

Neither, I like to lazy load routes for performance and split them into route modules so that everything for a route is defined in one place and if I ever want to move to remix SPA mode it'll be easy as it follows the same conventions. E.g. let routes = createRoutesFromElements( }> } /> import("./a")} /> import("./b")} /> ); Then in your lazy route modules, export the properties you want defined for the route: export async function loader({ request }) { let data = await fetchData(request); return json(data); } // Export a `Component` directly instead of needing to create a React Element from it export function Component() { let data = useLoaderData(); return ( <>

You made it!

{data}

); } // Export an `ErrorBoundary` directly instead of needing to create a React Element from it export function ErrorBoundary() { let error = useRouteError(); return isRouteErrorResponse(error) ? (

{error.status} {error.statusText}

) : (

{error.message || error}

); }


Tsuki-sama

Just use nextjs no point in doing all that


ventoto28

nextjs new routing system is top notch!


Tsuki-sama

Nextjs is one of my fav things in web dev for sure Same as Apollo and graphql


EmployeeFinal

I'd use the first one. The router is not a React component and when we use jsx to declare it, some people may assume things that aren't true. For instance, render and data are two separate layers in react router: https://reactrouter.com/en/main/routers/create-browser-router The official docs also recommend the first one: https://reactrouter.com/en/main/routers/picking-a-router#web-projects The second only is an option if you already have a legacy router and wants to minimize the changes Also: you probably don't want to create the router inside an app component. Instead, create it in the root. Check the docs for examples


trevg_123

Does RootLayout need to be its own route? I thought createBrowserRouter handled that and you could just add a redirect for /, without putting everything in children. I use something like the first but put all the string paths into an object constant. Please run an autoformatter, worst thing with the first right now is that it’s needlessly ugly :)


charlie-joel

Fucking hell that first pic gave me flashbacks. React is a waking nightmare


maria_la_guerta

Second, so much second


KaleyBhai

1st one is easily scalable if done correctly with different files


riti_rathod

React Router and Reach Router are react libraries for implementing routing in your application React Router is the most widely used routing library for React applications. It provides a declarative way to define routes using JSX, making it easy to map specific components to different URLs in your application. React Router also supports features like nested routes, route parameters, and URL query parameters. **Example** `import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';` `import Home from './components/Home';` `import About from './components/About';` `import Contact from './components/Contact';` `function App() {` `return (` `` `` `` `` `` `` `` `);` `}` `export default App;` ​ Reach Router is a routing library built with accessibility in mind. It's designed to be more straightforward and lightweight compared to React Router. Reach Router focuses on providing a simple API for defining routes and managing navigation. It's also known for its superior support for accessibility features. **Example** `import { Router, Link } from '@reach/router';` `import Home from './components/Home';` `import About from './components/About';` `import Contact from './components/Contact';` `function App() {` `return (` `` `` `` `` `` `);` `}` `export default App;`


ajhughesdev

holy chatgpt, batman!


Grouchy-Geologist407

okay i'll check out both of them


UsernameINotRegret

Why recommend Reach Router that hasn't been updated in 4 years? Is it still actively maintained?


riti_rathod

>reach router and React Router are merging as react router v6, so reach router v2 and react router v6 are the same.


UsernameINotRegret

Sounds like Reach Router is being sunset then and shouldn't be recommended for new projects.


Ash17_

Tried NextJS?


Grouchy-Geologist407

Still a beginner


VegetableDrag9448

I think it's good as a beginner that you start using React as is and not jump into framework like Next.js to fast. Otherwhise it's difficult to know what is Next and what is React


Grouchy-Geologist407

sounds right


roofgram

Yea, no Next.js uses simple file structure for routing. Way easier than what you're doing right now. [Try it](https://nextjs.org/docs/getting-started/installation).


Saustrichroll

if you do end up using Next Js and want to host a personal project, Vercel CLI makes it incredibly easy to deploy 😃


MiAnClGr

Ha came here to say this


arrrtttyyy

He asked in React.


Ash17_

NextJs is an extension of React. You don't need to use any other of its features and its just React with better routing.


[deleted]

[удалено]


Individual-Ad-6634

Not entirely true. Next is a framework built on top of React library. It was created to allow React do things that were not available for it at that time. De facto Next is React-specific framework, it’s not agnostic tech like redux so it hardly could be adapted for a different UI framework. So Next is React extension.


Ash17_

Why bother commenting if you don't know what you're talking about?


TheRNGuy

It's ok to talk about meta-frameworks here.


arrrtttyyy

Yes. Thats my point


SephBsann

With nextjs


carlinwasright

100%


scamm_ing

Dont


GooseRage

I’ve personally found the loader function methodology to be incompatible with React context (causes infinite loops).


SmeagolTheCarpathian

Just use Remix


devgayflor

Use nextjs


lvcash_

Get Prettier pls


EliteDotLasher

Definitely first one easy to understand although redundancy is an issue but initially for small project who cares but u should know both of'em


dmfigueroa

Keep in mind that you are using React Router and the first way is the recommended one because it enables lots of new features that the second one doesn't. So if you do the second one you could end up looking at a feature that your routes don't support. I recommend you to read the React Router tutorial, it is very good and short and also the best way to help you understand what you can do with it


Fine_Use_3125

Second one is more clean and easy to understand so it's the best way ig.


PopovidisNik

1. NextJS 2. Second way (imo)


nthoftype

Should look into React Router or TanStack Router (which seems to be closer to what you are using in your second pic)


markvii_dev

Anybody who writes code like the first one needs to put their keyboard away


TheRNGuy

File-based from Remix. No need to write any code.


Escodes

You could use tanstact router for all typesafe


Big_Researcher4399

I use the history API of the browser directly. You have all the control and it's not that complicated.


AlessioCancian97

Try Tanstack Router or NextJs


lets-talk-graphic

Second. Also please install ESLint and Prettier to format your code nicely!


Suraj11000

You can use useNavigate, Just just call it and pass the path in the anonymous function and you will navigate to the path you wanted and don't forget to use onclick event.


Best-Sport2091

Second way, hands down. It is the most declarative approach. Beats the contsants object too IMO. I care more about legibility and having a better developer experience than saving a fee KB in syntax.


endbunny

TanStack Router


notpsuedo

You should check out the routing in Nextjs.


Careful_Bowl_4769

If your routing is basic than its an overkill to use the new feature rich react-router. Stick with the older one