Staying Safe In a Concurrent World

Rate this content
Bookmark
Slides

With React 18 the long awaited concurrent features are now available to the public. While they technically do not introduce new restrictions about how we build our components, there are many patterns that previously worked but might now introduce subtle bugs in your apps. Let's re-learn the rules of React so that we can stay safe in this new concurrent world.

30 min
02 Dec, 2022

Video Summary and Transcription

The talk discusses the ramifications of the new concurrent features in React and the misconceptions around the rendering model. It explores the changes in the rendering process and the need to handle state carefully. The talk also highlights the challenges in managing communication with the outside world and the recommended libraries for synchronization. It mentions the benefits of using concurrent mode in existing frameworks and the difficulties in building demos and enforcing immutability. Finally, it emphasizes the benefits of concurrent mode for heavy components.

Available in Español

1. Introduction to Concurrent Features in React

Short description:

Hello, everyone. In this talk, I want to talk about the ramifications and implications of the new concurrent features in React. I will also introduce myself and explain the two groups of developers we have encountered. We will go back a few years to understand the vision for React and how it has evolved. The rules of React have not changed.

♪♪ Hello, everyone. I hope you're having an awesome conference so far. Maybe you even heard a couple of talks or visited some workshops or did some discussions outside there about the new concurrent features that were released in the newest version of React.

In this talk, I want to talk about exactly those features, but I don't want to showcase the APIs, the concrete APIs, but I'd rather focus on the ramifications and implications those features have on you as application developers.

Before we are going to jump into that, I like to introduce myself first. My name is Andreas and I'm a development lead at a small agency in Dresden and our job is basically to go into the project of other teams and help them make their code better, make their software work better, make their development process faster. In this process, we talk to lots and lots of developers from different teams and we noticed that there are more or less like two groups of developers. One group hasn't yet heard of the concurrent features and is doing something wrong in the application that might break when they use concurrent features. The other group is not using concurrent features because they are afraid something might break in their applications. So, many of them still aren't really using them.

And this is why I today want to tell you a bit about those new features to make sure that you can stay safe in a concurrent world. To get started, we first have to jump back a couple of years when Dan Abramov revealed the new vision for React. Back then, this feature was still called async rendering. The goal was to adapt to the user's network and to the user's device, so that even on smaller devices, the application could still feel responsive. And when the device is fast enough, that everything happens instantly without having any superfluous timeouts that you might not need in your applications.

Since then, lots has changed. For example, the release date. As you know, we don't have 2018 right now, so we had to wait a couple of years more. And many different topics changed as well. For example, the name. Back then, this was introduced as async rendering, or async react. It was then a bit renamed to concurrent mode or concurrent react, and then the team made the awesome decision to drop the mode so that you don't have to opt in your whole application into this new world. But they released concurrent features so that you as developers have the full control when the new behavior of react is used in your application and when not.

Back then, they even released this blog article where they made some preparations for this new feature. So, for example, they renamed some of the life cycle methods like component will mount, component will update, because they already knew that these functions were not safe for concurrent mode. They had to make certain adaptions because they knew where they were going, they knew their vision. So you could say in some sense that react has changed. But this is not true. This is the most important point of my presentation today. The rules of react have not changed.

2. React Core Rules and Misconceptions

Short description:

The core rules of React have not changed since 2016. Now, we can start making use of these rules to improve our applications. However, there have been misconceptions around the React rendering model, particularly regarding the atomicity of the reconciliation phase. In the earlier architecture, the reconciliation phase was guaranteed to be atomic. But with the release of React 16 and the introduction of the fiber architecture, the reconciliation phase can now be interrupted. Relying on the atomicity of the reconciliation phase was relying on implementation details, which can lead to problems.

The core premises and the core rules that we have to stick to as developers are still the same as back then in 2016. So the rules of react have not changed. We only start to really make use of them now. So all those years, we had to stick to some basic concepts like purity and no side effects without any real benefit. But right now, the framework starts really using that we are complying with these rules so that we can improve our applications.

You can see that from this design document. This is from more than seven years ago. And in here, it says that the core premise for the React library is that react itself is a projection that takes some data as an input and transforms that into an output so that your application is a simple pure function. So with the same input, it should always result in the same output. But since React didn't really use these rules in the application, they have been developing a couple of misconceptions around the React rendering model. And the first one is that the reconciliation phase of React is atomic.

Let me explain what reconciliation means. So whenever React updates, there happen two phases. At first, there's the reconciliation phase. So React calls your function components, generates those JSX elements, gathers them all together, and compares them to the previous version. This is the colloquial called virtual DOM. And then in the second phase, the commit phase, React is taking all those differences and applying them to the real DOM that we see as users in the browser. And back then, in the earlier architecture, it was a guaranteed that the reconciliation phase is always atomic because it was implemented that way.

Back then, we had the stack reconciler, that means React went through your application, through your components, started with the app component, then the app component renders the main component, so the reconciler went into this main component. So we have this stack inside of the React library that went through your application in an uninterruptible manner. So whenever React started with working on your app component, it could only do something else once everything else is finished. With the release of React 16, React changed this architecture to the fiber architecture. So we no longer have this stack of components inside of our application, but React internally keeps a list of components and can traverse this list iteratively and even interrupt this process. That means in the meantime, the event group and the browser has some air to handle user events. So the user scrolls, for example, but React is doing some calculations. React can pause those, handle the user event, update the user interface, or do something else, send some requests or something like that, but the reconciliation phase can now be interrupted and won't happen atomically. It's very important to note that it was never guaranteed that the reconciliation phase is atomic. It just happened to be that way because of the implementation. So relying on that was us relying on implementation details which now leads to problems. And for that I have a small demonstration application.

3. Changes in Rendering Process and Handling State

Short description:

So in this React application, the rendering process is slowed down artificially, and the reconciliation phase is no longer atomic due to the concurrent features introduced in React 18. This can lead to a tearing effect where different components showcase different versions of the state. To address this, we need to stop reading values that can change outside of the React world, such as global variables, and instead use hooks like useState or useReducer. Refs should also be used for objects that can be mutated around React without triggering a reaction.

So let's clear the console right now. What we have here is a simple React application where we have three blocks that display some state. Whenever I click on this re-render button, some state is updated and you can see in the console that the rendering is artificially slowed down. Each component takes something like five seconds to do its reconciliation phase, and then the commit can happen and we can see the update in the user interface. And even with React 18, this process is by default still atomic.

So when I click this re-render button and click on the change global state button, I'm just meshing that button until the rendering is done. Then we can see the reconciliation just happened as one large chunk, as one atomic unit, and only after that is done, can React handle the clicks that are made on the button. But now, with the concurrent features, this changed. So I have now the possibility to schedule a low priority update. So let's click on that button and mesh the change global state button. As you saw, we saw between those two components, the first block rendered up here. And then after this reconciliation phase of the first block, React had time or yielded to the browser. So the browser could inform us, yeah, there was some click events. So React could update this global state. And then after that is handled, React continued the rendering process with the next components, so with the second block and then with the third block.

This process is a bit non-deterministic because the browser decides when it's time to do what, so it's a bit hard to really showcase that. Sometimes the changes will happen between the second and the third component, sometimes both, sometimes the reconciliation still happens atomically. But we can see now that we no longer have this guarantee that the reconciliation phase is atomic. And we can already see the first problem. If we zoom in a bit here, we can see the first block rendered with a state of 26, the second block rendered with a state 35 because in the meantime I clicked the button 10 times, so the other components suddenly showcase a different state that is no longer up to date. So you get this tearing effect, so you see two different versions of your application, two different versions of the state within the application.

So we need to change something in our code so that this doesn't happen. And what we need to do is we need to stop reading values that might change outside of the React world, so no more reading some values that can change without React being able to know that they changed. This means we can no longer read global variables that are mutable. So for example, in my example, this global state is just a module level variable defined with let, and this is updated with the event handler. And we are reading this in the component, but React is just not able to know that someone changed this simple variable. For that we'd have to use the useState or useReducer hook. So we need to stop doing something like that where we read some global values inside of our component because these values might change during the reconciliation phase because it's no longer atomic. Same goes with reading refs. So refs are specifically made for objects that can be mutated around React without React having to react to that.

4. Reconciliation Phase and Commit Phase

Short description:

Whenever we read a ref during the reconciliation phase, we might encounter the problem of the user interface displaying different versions of the state. This also applies to reading the global state from a custom state management solution. React's guarantee of atomic commit phases no longer holds true with the introduction of strict mode and low priority features. The reconciliation phase can now occur multiple times before a commit phase, leading to potential inconsistencies in the state. This can be seen in our demonstration where the DOM briefly contains elements that are later removed.

So whenever we read a ref during the reconciliation phase, so for example, inside of the JSX, we might run into the same problem that the user interface shows different versions of the state. And the same thing goes whenever you feel like implementing your own Redux in 20 lines, for example, and you just read the global state from your custom state management solution. This is just the same problem. As long as this solution is not really integrated into React, then we might run into problems.

Let's come to misconception number two. It's that one reconciliation phase or one render always leads to one commit. So what we saw earlier, we have this reconciliation phase and then when this is done, then we have the commit phase. So only then is the user interface updated. So even if we split up the reconciliation phase, we still have the guarantee from React, and this is a guarantee that the commit phase is atomic because React doesn't want to display different versions of the state. React wants to showcase a consistent view of the state of the application. So the commit will always be atomic, but the reconciliation can have pauses in between.

And we now have the problem that we no longer have the guarantee that one reconciliation phase always leads to exactly one commit phase. You already heard about that earlier today from the talk from Nick, where he told you that with React's strict mode, React renders your components twice. So React already runs your reconciliation phase twice for only one commit phase. Now in the strict mode, there are even two commit phases. But this already breaks this combination that you have always one reconciliation phase and one commit phase. And we can also take a look at that inside of our demonstration. Let's first hide the blocks that we have available here and tick this checkbox that we want to display the commits. And now we are going to show the blocks. This will take again, 15 seconds, five seconds per block. And then before this is done, we are going to click the button to hide the blocks again. I'm clicking the Show Block and now I'm spamming the Hide Blocks button just so that it happens as fast as possible. We can see the reconciliation phase since I just scheduled a normal update. This is still atomic so we still go through all of the three blocks. The first one, five seconds, the second one, five seconds, the third one, five seconds. And then the commit happens. So, for a brief moment that was not really visible on the screen, but for a brief moment, the DOM contained those three blocks only for React to update once again because we clicked the Hide Blocks button to completely remove the elements again. So here we can see we have reconciliation phase and we have an update phase. Everything looks fine. But now when we use the low priority features from the concurrent features from React, we're clicking Show Blocks Low Priority and now spam again Hide Blocks.

5. Reconciliation Process and Outside World

Short description:

React stops the reconciliation process if it determines that the elements don't need to be rendered. Relying on React to commit after the reconciliation phase can lead to errors. Components should be pure functions that don't read or mutate the outside world during reconciliation.

And we can see the process is aborted. So only the first element was reconciled and then React stopped because React had time to handle the event, the click on the other button that changed the global state to hide the blocks again so that React knew, okay, we don't even need to render those other elements. Completely aborted this process so that the blocks were never visible in the user interface. So there we had a reconciliation phase on the first block without any commits. So whenever we rely on the fact that React will commit after reconciliation phase, we are prone to errors in our applications. That means again that we need to change our behavior. We need to stop subscribing or mutating the outside world within the renderer function, within the reconciliation phase. So again, our components have to be pure functions that don't read from the outside world if the outside world can change and we are not supposed to mutate the outside world within the reconciliation phase.

6. Handling Communication with the Outside World

Short description:

There are three options to handle communication with the outside world in concurrent React applications. The first option is to move the communication inside a UseEffect hook, ensuring a cleanup function is returned. The second option is to rely on popular libraries that are already concurrent-mode safe. The third option is to use the useSyncExternalStore hook provided by React, which allows syncing the application with external data. By choosing one of these options, we can ensure the user interface stays consistent and avoid tearing issues.

For this I also have a couple of examples. So for example, there are some libraries out there that register event listeners or register subscribers to some state management solution and they do that during the rendering process. So here we have this fictional component that creates a listener during the rendering phase and directly adds that to the window object. Now imagine this component never unmounts, then this listener will just be stuck on the window object and no one will ever remove that, so we have a memory leak introduced to our application. Luckily, this problem does not really occur too often in applications.

This is more happening in library code and so whenever you stick to popular libraries, you won't really run into that problem, but it's still important to keep an eye on that, that you don't mutate the outside world, don't build up a connection, don't create web sockets and stuff like that because this might break when we use concurrent features. However, it still has to be possible somehow to do these things, to read from global values, to mutate the outside world, because in the end, our application is made to communicate with a server, to communicate with the user, to display some changing state, so there have to be some solutions.

The first one is to just move all of this communication inside of UseEffect because UseEffect is made that we have the build up, so we can make a connection at event listener and stuff like that, and we have the cleanup, so we just return another cleanup function from the UseEffect and can clean up if we build some connections, so we add an event listener and then we remove it again when the component is unmounted. And since we always have this guarantee that there will always be a cleanup after the UseEffect call, it's safe to do something like that inside of UseEffect. So we always have this pattern that you have a state variable inside of your component, you read from the server inside of UseEffect, update the state variable, and then you're good to go. The problem with that is that during the first reconciliation phase, the effect has not been called yet, so whenever you require to display something from the UseEffect call, you have to do the first reconciliation phase without this value because it will only be present in the second phase when the state has been updated.

So the second option is to pick a library that fits your use case. If you pick React Query to do communication with the server side, if you pick something like Redux Toolkit to handle your state management solutions, you can pretty much rely on the popular libraries to already be concurrent-mode safe or concurrent-feature safe because React team has been working quite closely with the maintainers together in this RFC process so that these libraries are already concurrent-mode safe. And the third option is if you really want to handle your own solution is to use useSyncExternalStore. This is a hook that React provides us that we can use to sync our application with some external data. For that, you first have to define a subscribe function, but you again have this notion of a buildup, a constructor, so to say, and to cleanup where you have to guarantee that these will always run in pairs. So here, for example, we add an EventListener to the global resize event and we make sure to remove that again once this sync process is cleaned up by React. After we did that, we can build a custom hook, use windowWidth, for example, and use the hook useSyncExternalStore where we pass in our subscribe function as the first argument, and the second argument is the value that reads from the outside world. And now React can absolutely be sure to control when this reading function is called so that React can be sure that this value never changes during a reconciliation process so that the user interface always stays consistent. That way, we can use our custom hook, use windowWidth, wherever we want in our application, and can use the value during the initial render of our component and can be sure that during updates, it will stay up to date as well and not introduce those tearing issues. That means when we use one of those three options, we can just go back and relax and let React do its thing because the React team designed React in a way that we live above this abstraction level. So in the ideal world, we would never wonder how many times our reconciliation phases are called because React might make some decisions in the future to call them more often, to call them less often, to skip some or to recall them. If React is able to rely that these functions are pure, then React can decide these things for us and can make optimizations without our code breaking. So with these assumptions, it's now possible again to lean back and stay safe in the concurrent world of React. Thanks for listening. Thank you ever so much. Thank you. Thank you. Thank you ever so much. If you'd like to join me here, we've had some questions.

7. Common Mental Models and Managing State in React

Short description:

When working with React, it's important to understand that mutating values outside of React is not supported. Developers need to change their mental model and use hooks like useState or useReducer to manage state changes. React requires full control over state changes to ensure consistency.

Just a reminder for the audience, you can open up Slido at any point and ask questions to our speakers today. We only have a couple in right now, so by all means, do ask questions. We'll probably have time to ask them. So thank you once again for your talk. I'll crack on with the first question we have, which is, what are some of the common mental models that you see in developers that lead to mutating values outside of React? I think it's just the normal way of thinking that for example, when you have a variable that you can use to display information in the user interface. The same thing goes for updates. We have a feature in JavaScript called let, and you can use that to define variables that you can change in the future, but React does not allow that, or React does not want that and probably support that. So there definitely are some learning curves. It's especially important when you're introducing React developers with other backgrounds to the React world, because you have to definitely change your mental model to come into this world where everything that changes needs to go into a use state or in a use reducer, because only then React has the full control over that.

8. Linting Potential Issues in Component Usages

Short description:

Is there any way to lint potential issues in component usages? Definitely. There are already many lint rules in place, such as the dependency arrays for effects. Rules regarding mutations, like mutating arrays or objects, also exist. Hooks rules are important, as well as rules regarding mutations and mutable variables.

Excellent, thank you. The next question which is having, wow, so many upvotes, so quickly. Elon Musk, I guess? Is there, don't worry, this is a lovely audience. They will only ask you the most lovely questions. Don't worry. Is there any way to lint potential issues in component usages? Yeah, definitely. And there are already many lint rules in place. For example, one of the important things are the dependency arrays. So whenever we use the effects, we need to add those dependencies so that the effect always runs at the moments where we need them to run. I guess it's also quite possible that there exist rules regarding mutations, because whenever you mutate an array, mutate an object, we can already know, okay, this breaks these assumptions about the immutable world of React. So I know definitely about the hooks rules, which are quite important. And I guess there should also be some rules regarding mutations, mutable variables, and stuff like that.

9. Recommended Libraries for Synchronization

Short description:

What libraries would you recommend for managing synchronization in React? Popular options for data fetching include React query, which is built into many other libraries. For state management, contenders like Zustand, Yotai, and Valtio are built specifically to handle the problems that can arise from concurrent features.

Excellent. Thank you so much. Okay, so what libraries would you recommend? You mentioned three solutions, the middle being using libraries. I know you said it was very dependent on use case. Are there any kind of first options that you might reach for to manage this synchronization? So I think the popular solutions are just for data fetching, is something like React query. We saw earlier in the TRPC talk that this is built in into many other libraries because it's just so reliable and they're handling those problems quite well. And for state management, it's just the usual contenders like Zustand, Yotai, Valtio, and stuff like that, which are just built for that because the maintainers of those are already also quite aware of the problems that might be caused by the concurrent features. So whenever you pick something that's popular and used and actively maintained, you can be sure that the team's communicated with the React team and you can rely on that, I think.

10. Benefits of Concurrent Mode in Existing Frameworks

Short description:

Are there any visible benefits of using concurrent mode in existing frameworks like Gatsby or Next? It's really hard to showcase the benefits, as demonstrated in Twitter discussions. The Rack team believes there will be benefits in scheduling the rendering process, but it's difficult to provide examples. Time-slicing features are important for client-side rendering, especially for applications with interactive charts. Static pages pre-rendered with Gatsby may not show noticeable differences.

Cool. Are there any visible benefits of using concurrent mode in existing frameworks like Gatsby or Next? I'd first like to go into the detail on the first point of the question. I think it's really, really hard to showcase the benefits of that. There have been many, many Twitter discussions where that came across, where some people made some demonstrations with some cubes spinning in a div and where the framework could be maintained with concurrent features. And then other library maintainers come in and say, our library is so fast, we don't need this concurrency. So it's really, really hard to tell if there will be really some tangible, measurable benefits. The Rack team has this vision that since it's theoretically possible to schedule the rendering of the reconciliation process, that there will be benefits there, but it's really hard to showcase some examples there. But in theory, it should be quite clear that whenever the framework is able to decide what it wants to work next on, because some things are more important for the user as others, there should be some benefits there, but it's again really hard to showcase them. Regarding the integration into Next.js and Gatsby, all those features are especially important for, so these time-slicing features are especially important for the client-side rendering. So whenever you have applications that do a lot on the client-side, so some interactive charts where you can filter the data, for example, then it becomes really important that the scheduling can really show the benefits. When you have a static page that is pre-rendered with Gatsby, for example, and just displays a blog article, you probably won't notice any difference anyhow.

11. Building Demos and Documentation Challenges

Short description:

Finding it difficult to build demos for abstract concepts, the React team struggled with the Sierpinski triangle demonstration. They realized it was a contrived example and moved away from it. Documentation and sample app building is always a challenge.

Yeah, awesome, thank you. And yeah, finding, you know, one of the more difficult things with building demos for these slightly more conceptual, abstract concepts is that they can be a little bit conceited, and therefore it's hard to... I think the React team also struggled with that because in the beginning, they had this Sierpinski triangle demonstration where the triangle was made larger and smaller, and they quickly realized that this only makes really sense when you add some artificial delays, like in my demonstration, because then you can see the effects of these features and you can demonstrate them, but they since moved away from that because they realized these are just really contrived examples, and it's really hard to imagine how that affects us in our applications. Yeah, forever the challenge with documentation and sample app building.

QnA

Enforcing Immutability and Real-World Use Cases

Short description:

Would banning the 'let' keyword to enforce immutability be fair? Working with concurrent mode brings extra complexity, but it's optional. React can render two universes at once. Real-world use cases for concurrent mode are rare but include rendering many components where each takes longer than usual, such as in charts or 3D rendering.

Right, we have a couple more questions. We might have time for a couple more still, so if you have questions, don't be shy. So would you enforce, or perhaps, consider banning the let key word to enforce immutability? So I personally wouldn't. I could understand if some do that. There are some people in the community that always use let because it's just three letters instead of five letters, so it's just shorter, and I think it's just a matter of preference. The longer you work with React, the more those patterns of mutations and updates stick out like a sore thumb. In a code review, it becomes quite clear, quite apparent when someone uses that, and then you can see if someone uses let, okay, what's happening here? Is that okay or not? Because there are situations where this is totally fine to lose a let variable. For example, if you have a function in a side of that function, in an event handler, for example, you want to update a variable, it's totally fine to do that as long as you don't mutate anything that is already shared with React so that React can always keep track of the data. So as soon as you share something, then you must stop the mutation and with this precondition, it's quite hard to completely ban something because there are still available use cases for doing that.

Yeah, absolutely. So this question is, would it be fair to say that working with concurrent mode now brings extra complexity when working with external libraries? I think this is one of the main complaints that have been brought up is that it seems like all of a sudden, React got a lot more complex with that. In the early days when you had those guarantees which were not really guarantees that everything happens just once and everything happens from start to finish, it was just simpler to reason about the internals of React and to include that in your features that you were developing. And now there is this new layer of complexity. Then Abolrov mentioned on Twitter that he likes to think that React is now able to render two universes at once, two versions of the state. And I think I wouldn't have come up with the idea of using a UI framework to render two universes, which I think showcases quite well that yes, it becomes more complex, but only if we really want to make use of those concurrent features, because we can also decide as a team to just don't use them, and then we are basically good to go.

Cool. This is probably the last question we'll have time for. And thank you very much to everyone who submitted. We ended up with somewhat of a surplus, and that's absolutely fine. After this Q&A, Andreas will be over in the speaker Q&A section over in the networking area. So please, if you did ask a question that we don't have time for, or if you think of more in the meantime, please feel free to head there for the next few minutes and ask us directly. So this last question, which I think is kind of a fair follow-on from some of our previous ones, is can you think of any good real-world use cases for where concurrent mode really shines? Yeah, I think one of the, so you have to have a use case where you have many different components and where each component takes a bit longer than usual. So for example, you have, to render one frame, you have 60 milliseconds. So for example, you could say you have like 1,000 components and each takes two milliseconds. This is a perfect use case because React can then go through like eight components per rendering cycle, then you to the browser make some updates and then continue with this rendering process. But these use cases are really rare because when you have a list with 1,000 elements, you first start to virtualize that list so you only render the first 10 elements that are visible. That is why I think many of the demos use something like charts because in charts, it happens quite often that you have like 1,000 data points within one chart. But then the problem is, calculating one of those data points is oftentimes quite cheap. So we don't really run into the benefits of that. Paul Henschel from React 3.0 Fiber always showcases some interesting demos because there he's doing lots of stuff with 3D rendering in the browser.

Benefits of Concurrent Mode for Heavy Components

Short description:

When you put 3D stuff into a component, it can grow in size quickly. This is a good use case for the concurrent features in React, especially when dealing with medium-sized heavy components.

And there you have this, when you put a component, when you put like 3D stuff into a component, this one component can grow in size quite quickly in performance-relevant size. So this is, I think, a pretty good use case. And this is why he's a pretty big advocate for those features because there, you can really make use of them because you have a medium amount of kind of heavy components. And this is, I think, the situation where this shines the most.

Excellent. Thank you ever so much. Thank you from me and I'm sure on behalf of the audience who are going to give you a massive round of applause. Thank you for such an insightful talk. Thanks a lot for having me. Having a pleasure.

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
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
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 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. 
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.
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.
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!

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
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
Top Content
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