Incrementally Adopt Modern React Patterns in a Legacy Codebase

Rate this content
Bookmark

In this workshop, we’ll look at some of the approaches and techniques that can be applied when making refactors or adding new features to a legacy React codebase to bring it inline with the latest approaches. We’ll cover topics such as how to use React Hooks to share component logic in a way that will allow reuse in class components; how to incrementally introduce other patterns to a React Redux app; and how to build in flexible UI components via abstractions where we are tied to some global CSS or a component library. Along the way, we’ll touch on many React patterns and state management approaches with the ultimate aim of being able to evaluate these options and let our requirements drive the architecture in moving towards a more robust and maintainable codebase.

Richard Moss
Richard Moss
130 min
09 Jun, 2021

Comments

Sign in or register to post your comment.

Video Summary and Transcription

This workshop focuses on incrementally adopting modern React patterns in a legacy codebase. It covers topics such as building reusable component logic hooks, refactoring legacy code to use hooks, and using context with hooks. The importance of refactoring class components to functional components and using hooks whenever possible is emphasized. The workshop also explores the use of Redux for centralized state management and the use of context for global state. Troubleshooting and error handling are discussed, and the workshop provides exercises for hands-on practice.

1. Introduction to the Workshop

Short description:

Welcome everyone to this workshop about incrementally adopting modern React patterns in a legacy codebase. I'm a software engineering coach and currently a principal engineer at Sainsburys. I've worked on various projects and have experience in training developers. Let's get started.

I guess I was just gonna ask quickly. I guess everyone's in the Discord channel. You can probably see my screen now, hopefully. That's where I'm gonna sort of post all the stuff. If you want to, yeah, feel free to clone and run the installs on the repo now, just save time later. I mean, there will be time, but, you know, it always takes a couple of minutes. But, yeah, I guess we can just start, actually, because it's 5 past, I think. Hopefully more or less everyone's joined. But, yeah, well, let me just present this. And, yeah, if you can't see what I'm presenting or talking about, feel free to just shout out. Like, if you can't see on my screen, or the code or any of those things, just let me know, I'm going to present it in full screen. I don't have two monitors now, I can't tell exactly. But, anyway, welcome everyone to this workshop about incrementally adopting modern React patterns in a legacy codebase. Yeah, you might be wondering who am I quickly, thanks for everyone's introducing themselves as well, that's really nice. Who am I? Software engineering coach, currently principal engineer at Sainsburys. For those of you that have visited the UK, you probably know Sainsbury's, big supermarket. Yeah, I've worked on lots of different things, I've been lead developer on several projects, at leen.js, my previous place where I was a partner. I've done plenty of training as well. I work with React, Kurl Academy, I was the organiser of the boot camps we were running in Portugal and London a couple of years ago. And we did sort of like trainings for developers from all sorts of places. Cool. Let me see if I can go to the next slide. Okay. Cool.

2. Introduction to React Patterns and Hooks

Short description:

Welcome to the workshop on incrementally adopting modern React patterns in a legacy codebase. We will cover building reusable component logic hooks, refactoring and simplifying a legacy React Redux app, and using context with React hooks. We will also discuss the evolution of React patterns, from functional stateless components to the need for class components and the introduction of hooks. Let's explore the circumstances where class components or hooks are needed. Managing state and lifecycle methods were the primary reasons for using class components in the past, but now we have Hooks alternatives for most cases. It's important to keep components as functional components whenever possible. Let's dive into the evolution of React patterns and how we can share component logic.

Welcome everyone to this workshop about incrementally adopting modern React patterns in a legacy codebase. I'm a software engineering coach and currently a principal engineer at Sainsburys. I've worked on various projects and have experience in training developers. Let's get started.

What are we going to see today? This is a bit of an agenda about the idea, the big idea of this talk is how can I improve my legacy React codebase. I'm sure everyone on the call has probably been there. You get onto a new codebase because it's a new job or just when you haven't worked on before at work and there's a bit of legacy code around. There's a lot of different trade-offs when it comes to making different refactors and how to modernise things, and really the ones that you choose, I think, should depend on your objectives. It's always really good, saying this at work, we should let our requirements drive the architecture, and so, yes, we have to think a bit carefully about some of those trade-offs but we will go into some of that in a second. What are we going to see during this workshop? We will see how to build some reusable component logic hooks and how we go about applying that inside class-based components, so how you can incrementally move towards those using hooks and keep using that logic. We will also chat a bit about refactoring and simplifying a legacy React Redux app, starting with what is the point of Redux, what are some of the things that have come in to give us more options, let's say, and how could we think about managing that, and also we will chat about context because it feeds nicely into that, and how we can use context with React hooks for when we want to manage a piece of global state, or I put global in italics because you need to broadcast to components across the tree. Those are the main things we will be having a look at in this session. So, yes, let's get into it. Oh, and then up front a couple of things as well. There will be a couple of breaks. What we will do is I will try to keep the parts of the presentation down to about 30 or so minutes, probably, and then we will do some exercises within that code base inside the breakout rooms, and I will do a little live coding, show you around the exercises, we will do that, and then there will be a couple of ten-minute breaks in between as well because this session is going to go on for some time. For the presentation part, I guess it might be easier if we just do questions at the end, but I promise I will try not to speak for more than 20 or 30 minutes in any one go without stopping. Let's get into it. Let's talk about hooks and why this sort of came about. I think it is important to understand a little bit about the history of how we got here and things, and then we can rationalise about this stuff in a better way. The whole that this was introduced in React was in versions below 16.8 there wasn't a stateful primitive and I'm sure everyone here remembers class components, which led to several big problems. This wrapper hell which you can see on the right-hand side, we will talk more about that, but this is the idea you had to keep wrapping stuff in order to get in the dependencies more than you needed, because components were really just getting stuff from the outside via props for 95% of the time anyway. It also led to really big components and when things get large, they don't get they're hard to read and they're hard to reason about and I think that should always be like one of our KPIs, readability because it goes to maintainability as well. It wasn't very good. Also, it turns out that classes are confusing for both people and computers. There were a lot of things when we were using this class syntax and bear in mind classes in JavaScript are syntactic sugar. That isn't how it works under the hood, right? But it's confusing with this key word and you've got this class property syntax which you could use, but only if your babels configure correctly and all of that type of thing. So that's the people part and it turns out for computers, as well, when it comes to minifying, it didn't quite minify as well. So it was tricky for that and it actually way sort of went against the spirit of the library, I guess, because when it was first conceived, it was conceived with a sort of functional approach in mind, but the class syntax was needed in order to introduce things like the life cycle method. That's why we ended up with it. There was an idea that it would go away at some point, which is all of the reasons why hooks has kind of come about. Cool. So I guess a question for all of you, like what are the circumstances that we needed to use a class component or now like need to use hooks? Can you kind of think of like two, like in what circumstance you need to do that instead of just using functional components? Anybody want to have a crack at that one? At least, I'm sorry go ahead. Sorry, one thing I can think of is for ErrorBoundaries still needing the classes for that. That's true. Yeah, good one. Definitely still need it for the ErrorBoundaries actually, yeah. But like why specifically do we need it for the ErrorBoundaries? What is it about the, there's something here that was applicable in the past as well that you use in ErrorBoundaries that is why you would have to use the class. Oh, okay. That thing, that part I can't remember. How about to manage state? Yes, exactly. That is one of the things very good. Exactly managing state, right? We always had to use the class components to manage state previously. And obviously, now we need to use the use state hook. Yeah, very good. That's one of them. And the other one, we almost got there with the ErrorBoundary, but it's basically life cycle methods. Because actually that ErrorBoundary, that component, the cache, that is a life cycle method. You need to be in a class to use a life cycle method. But basically, for most of them, except the component that cache, we have Hooks alternatives now. But essentially, it's those two cases. This question is a really interesting one to ask yourself. Because I used to see this a lot with code bases and developers, where people would be building class components and not really need to do so. It's always err on the side of like keep your components as functional components and not be like, keep your components as a component. Now, I think stateless components are a really good choice. And as I said before, we're talking about functional components. They used to be called functional stateless components, right? But obviously, that's not a very good name for them anymore, because obviously, they can have state. So yeah, functional components. So let's talk a little bit here about the evolution of React patterns. So as many of you are probably aware, if you've been working with React for a while, well, and even up to date, we still use this one. And we're still using React as a standard programming language. We're still using React.js. We're still using React.js. But now, we're using React.js. And it's a great way to separate our UI and our logic, right? So those presentational components were what we called in the past the functional stateless components. They're just functional components. So they are functions that just render a piece of JSX, right? And they shouldn't really manage any state. They might take, like, a callback or something which was passed down via props, et cetera. So this was a really useful pattern for a long time. And in some cases, we can still try to do that, right, to just separate our concerns a bit. This sort of led to this next pattern that came along, where we said, okay, that's great. We've separated UI and logic. But how can we share component logic? And when I say component logic, I mean these things that we mentioned before, which is like any logic that is associated with lifecycle methods or with stateful logic. In that case, you need to sort of do something else.

Watch more workshops on topic

React Performance Debugging Masterclass
React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured WorkshopFree
Ivan Akulov
Ivan Akulov
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 🤐)
Concurrent Rendering Adventures in React 18
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
Maurice de Beijer
Maurice de Beijer
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 Hooks Tips Only the Pros Know
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
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, TypeScript, and TDD
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
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.
Web3 Workshop - Building Your First Dapp
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
Nader Dabit
Nader Dabit
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.
Designing Effective Tests With React Testing Library
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Top Content
Featured Workshop
Josh Justice
Josh Justice
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

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

A Guide to React Rendering Behavior
React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
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
Building Better Websites with Remix
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 Compiler - Understanding Idiomatic React (React Forget)
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
Top Content
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
Using useEffect Effectively
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
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.
Routing in React 18 and Beyond
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
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.
(Easier) Interactive Data Visualization in React
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!