Routing in React 18 and Beyond

Rate this content
Bookmark

Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.

In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.

20 min
17 Jun, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Routing in React 18 brings a native app-like user experience and allows applications to transition between different environments. React Router and Next.js have different approaches to routing, with React Router using component-based routing and Next.js using file system-based routing. React server components provide the primitives to address the disadvantages of multipage applications while maintaining the same user experience. Improving navigation and routing in React involves including loading UI, pre-rendering parts of the screen, and using server components for more performant experiences. Next.js and Remix are moving towards a converging solution by combining component-based routing with file system routing.

1. Introduction to Routing in React 18

Short description:

Hey, everyone, I'm Delba from Vercell. Today, I want to talk about routing in React 18 and how it will change the way developers view applications. Routing has evolved from multi-page applications to single-page applications. Single-page applications bring a native app-like user experience. The client-side decides what content to fetch and render. Applications are transitioning between different environments, client or server.

♪♪ ♪♪ Hey, everyone, I'm Delba, and I work for Vercell. As some of you may know, we're the creators of Next.js, and I'm curious to know how many of you here use Next.js? Wow, so that's a lot of you. That's amazing. So, although we created Next.js, we also have a platform, Vercell. And funnily enough, Vercell supports over, I think, something like 35-plus front-end frameworks. So even if you don't use Next.js, you could still use Vercell.

And today, I want to talk to you about some exciting stuff we have been working on, which is routing. And routing in React 18. Now, as you may know, a few months ago, React 18 was released with new concurrent features. And on the React blog, the team mentioned that they expect concurrent features to have a big impact on the way that developers viewed applications. So today, I want to discuss with you what this impact could mean and how we will change how developers view applications, especially with React Server components, as well. And this may not also change things for Next.js but also for other frameworks and library maintainers. And I'm going to specifically look at routing, but I will also mention data fetching and rendering, or as I like to call them, the three pillars of the web, because those terms are very much interconnected.

Now, to give everyone here some context and also the people who might be watching online, I think it's important to just take a step back and look at how routing has evolved in frontend applications. Now, please note, I'm going to be condensing years of routing history in like five minutes, so there's a lot more nuance. And one way we can look at routing is through the type of applications we can build, multi-page applications, single-page applications and, more recently, hybrid apps. So in the very early web, routing was very straightforward because if you think about it, each URL mapped to a specific file on a server. And then later on, using dynamic server-side languages, we were able to generate a response from the server for a specific route. In a traditional multi-page application, routing is done on the server, and navigating between pages causes the full page reload that we're all very used to. Now, when native mobile apps came along, they brought smoother transitions and new UI patterns. And single-page applications, you could say, were the web's response to native apps. We wanted our websites to feel like native apps. That is to say, we wanted them to have the same user experience as native apps. In a traditional single-page application, routing is done on the client-side. So on initial load, you may see a white blank screen while the client-side fetches and renders the content. Now, when you navigate on a single-page application, the client will dynamically rewrite new content. And for a given route, the client is deciding what content to fetch and render. And last year, Rich Harris, the creator of Svelte, gave an amazing talk on the whole MPA versus SPA debate, where he discussed some of the pros and cons of each. It's a really great talk, and I recommend watching it if you haven't had a chance to do it already. But one takeaway from that talk that I want you to remember is that he recognized that there's an emerging pattern in our industry, where applications are transitioning between different environments, client or server.

2. Overview of Routing in React

Short description:

And he called those type of applications transitional apps. React Router's approach to routing is what I like to call component-based routing. Next.js took a different approach to routing using file system-based routing. The React team gave us an early Christmas present that will allow us to move towards more hybrid solutions.

And he called those type of applications transitional apps. And transitional apps, they try to combine the benefits of both the client and the server, because if you think about it, why not both? So that's kind of like a broad overview of routing on the web. Now let's zoom into React.

While React didn't invent single-page applications, you could argue that they contributed to their popularity. The fact that React was and still is mainly concerned with UI and rendering means that the community has come up with a few different solutions for routing. And one client-side solution that quickly rose to popularity was React Router. Now, how many of you have used React Router before? Yes.

So React Router's approach to routing is what I like to call component-based routing where you use code to map specific components in your application to your URL path. And if you combine it with a tool chain like create React app, then you can easily create single-page applications. And this leads to I think not just the adoption of React itself, but also applications that were fully client-side rendered.

Now, in 2016, a few years later, Vessel introduced Next.js. And Next.js was created as a framework to help developers build server-side rendered applications. And Next.js took a different approach to routing. It used what I like to call file system-based routing, where files in your application map to your URL. And although Next.js felt very similar to a multi-page application, it actually used prefetching and client-side navigation to give applications a Spar-like feel, if you could say.

Now, another incremental step towards hybrid apps was the Next.js data fetching methods, like getInitialProps. And what these data fetching methods did was move the fetching outside of your rendering code or outside of your component so that you could fetch data both from the client and the server. Now, I'm focusing on Next.js today. But it would be remiss of me not to acknowledge some projects that are also working on routing solutions for React, including Shopify's Hydrogen, Remix, and also Redwood. So fast-forward a few years in early 2020, and the members of the React team were publicly discussing moving more rendering work to the server.

The idea was that if we are doing data fetching on the server anyway, could we move some rendering work to the server and, therefore, reduce the amount of code that gets sent to the client? Now, you can probably imagine the hot takes that followed that tweet. I think it can be best summarized as, this looks a lot like server-sided routing. Are we going back to MPAs? But to quote a not so serious meme from one of my favourite people on Twitter, this is less of a pendulum swing and more a spiral of incremental improvement. So switchbacks. Not purely SPA, not purely MPA, but a kind of spike in convergence towards hybrid. That benefits from both the server and the client. And each time this conversation was brought up, the reacting was careful to emphasize that they were looking for a hybrid solution. And one important thing to note here is that this hybrid solution wouldn't be creating additional requests to the server. It would take advantage of a request that has to exist anyways. So, in December 2020, the React team gave us an early Christmas present that will allow us to move towards more hybrid solutions.

3. Routing with React Server Components

Short description:

That was React server components. We now have the primitives to address disadvantages of multipage applications while maintaining the same user experience. We proposed a new router for Next.js that enables routing, rendering, and data fetching on the server. With React server components, we can interweave client and server components. Breaking up routes into independent fragments has three main benefits: creating layouts, reducing re-rendering, and having more granular control over data fetching. By building a new route with React server components, we reduce code sent to the client, server workload, and loading time. Combining with concurrent features simplifies loading states and improves navigation experience.

That was React server components. When you combine React server components with suspense and the streaming, we now have the primitives or the building blocks to address some disadvantages of multipage applications or server side rendered applications while maintaining the same user experience we love about single-page applications or client-side applications.

But there is one last piece to the puzzle. And in the last few months, the Next.js team has been considering this. If we need to go to the server to do a trip for data fetching and now we're going to the server to do rendering with React server components, could we possibly also do routing on the server? Could we enable developers to build applications where routing, rendering and data fetching happens where it makes more sense? And could we give them conventions that are easy to understand but also allows them to move parts of their application either to the client or to the server?

So a few weeks ago, we shared an RFC. And in this RFC, we proposed a new router for Next.js. And this new router builds on top of React components and React 18 features. There's a lot more detail in the RFC and I won't go too much into the implementation details. If you're curious to know more about it, I do recommend reading it. But for now, let me just share with you something that I'm most excited about and that we've been working on.

So, if you think about it, with React server components, we can interweave client components and server components in a tree. This means that in a page or a route, you could potentially have both client and server components. So, with this new model, it becomes increasingly important to break up our routes into independent fragments which we call route segments. These route segments, they map to an already existing term, URL segments. Although we are breaking up the routes, we want to maintain file system routing because generally it tends to be a more intuitive way for developers to define their routes. And breaking up the routes like this, or as we call it, doing nested routing, has three main benefits.

The first one is that we are able to create layouts, and layouts have been a very long, like, going-back community ask. And the way that we want to define layouts is that a layout is UI that is shared across routes, and these layouts, they shouldn't re-render or lose state on navigation. It also means that components that don't change within a route, so a layout, we also want to make sure that they are still interactive as the user navigates between routes. Secondly, if we combine it with server components, that means that on navigation, the server only has to fetch and render the segments that have changed, and we don't have to re-render the whole subtree for that route. And thirdly, we can have more granular control over data fetching. So in Next.js, as you may know, currently we fetch data on the page level, and with this new model we can fetch data in the segment level. And since we already moved data fetching outside of the rendering code or outside of the components, what we can do now is we can eagerly initiate those requests in parallel. And this reduces what some of you may be familiar with, which is waterfalls. And overall, the amount of time that it takes to load the content of a route is also reduced.

So by building a new route with React server components, we're able to achieve three things. Reduce the amount of code that we send to the client, reduce the amount of work the server has to do, and also reduce the amount of time that it takes to do that work. Now, if we were to combine it with concurrent features, such as transition, suspense, and the feature off screen component, we can simplify the creation of loading states and improve the navigation experience. For example, if you want to use client-side routing and you are fetching as you render, you may have too many staggered loading states or spinners. So, really, what you want to do as a developer is consolidate them into fewer more meaningful loading indicators.

4. Improving Navigation and Routing in React

Short description:

When using server-side rendering, it's important to include loading UI to indicate background work. Pre-rendering a small part of the screen improves navigation by providing immediate feedback. Stashing routes allows for restoring state when navigating. React's server components enable more performant and smoother experiences. Creating shareable experiences without breaking URLs requires simple conventions for complex routing patterns. The React team provides the primitives for building hybrid applications.

On the other hand, if you are using server-side rendering, you have to fetch and render the content before navigation starts. So your application will appear unresponsive as the work is being done on the server. So, in that case, you do want to include loading UI to indicate that work is being done in the background.

In other case, we believe the framework should provide an easy convention that will allow developers to create loading states. Now, we can also improve the navigation experience further by pre-rendering a very small but minimal part of your screen. So, this means that when you navigate between screens, the navigation will be immediate, and the user might see something like a cover photo or title before the rest of the content loads.

And in a similar fashion, and this one is one of my favourites, is that we will be able to stash routes. And what that means is that we can stop the previous routes and then pre-render future routes so that when the user navigates between the routes, we restore the state. Now, I'm running a little bit out of time, so I'm just going to skip these two slides, but... If you do want to find out more, we do have more information in the IRC. What I wanted to highlight here today is that there are many ways you can think about routing in React, and we have been thinking a lot about how we do routing in XJS. It's not about routing itself, but it's what routing will enable us to do. So, we'll be able to create more performant experiences with React's server components and also smoother experiences by improving navigation. We also want to make sure that we create experiences that are shareable, that don't break the URL. And to do that, we need to create simple conventions that will allow developers to implement more complex routing patterns. So, last but not least, before my time is up, I want to take a moment to give a shout-out to the React team, because they're the ones giving us the primitives and the building blocks for us to be able to build the next generation of hybrid applications. Thank you so much. APPLAUSE Thank you. You want to go? Yeah. APPLAUSE All right. It was a blast. I don't know exactly what new React feature it was, but there was a certain point, there was a new feature that was released, and we updated our app, and it felt so fast that I didn't trust it. It feels like every app is going to be like that now, right? And every now and then we get a new feature in React that's just... Yeah. Yeah. It's too fast. You don't believe how fast it is. That becomes the new normal, and you're like, damn, this takes a long time. Yeah. So thanks for your talk.

5. Next.js and Remix: Converging Solutions

Short description:

Next.js is not adapting the vision of Remix, but rather moving towards a converging solution. Remix combines component-based routing with file system routing to create nested routes. This approach is also seen outside the React ecosystem. The industry is moving towards combining component-based routing with file system routing, borrowing ideas from each other for incremental improvements.

Great information, by the way. We're going to jump into the audience question. First question is from Martin. Is Next.js adopting the version of Remix on component-based routing here? Is it the same? Yeah. That's an interesting question. So when I think about Remix and the work that they've done in React with routing, they've done an incredible work. There's no doubt about that. And if you think about it, most applications use React Router, which are from the creators of Remix, as their backbone. Now, when I think about Remix itself, I don't really see it as adapting the vision of Remix as much as moving towards or converging towards a better solution. So what Remix has done really well is they've combined the idea of component-based routing with file system routing and created nested routes. Which makes sense because file system routing is easier to implement, but then with component-based routing, you can map your components to your URL path. I think that is a great approach, but I also see it outside of the React ecosystem as well like for example with StealthKit. So I think overall as an industry, we're just moving towards that solution of combining component-based routing with file system routing. And it's borrowing ideas, right? Sorry? We're all borrowing ideas from each other and trying to improve the whole ecosystem. Incremental improvements.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
Top Content
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn