Epic Web Conf late-bird tickets are available now, hurry!

Get your tickets here

Join the community and network with other great web devs.

Time's up. The sale is over
Back to overview

A Rundown Of What's Next For React With Dan Abramov

Dan Abramov talks about the future of React.

What's next for React? In this second interview with Dan Abramov React's direction is discussed along with overviews of exciting new features.

Dan gives a great rundown these incoming features. React suspense is going to provide a baked-in solution for the problems that async data fetching causes with component rendering, and concurrent mode is bringing non-blocking rendering. Further insight is provided into what problems sparked the need for these new features and why they were the chosen implementations.

There's also discussion on React Fire modernizing React DOM, JSX v2, if React is a framework or a library, what React is intended for, and React's end-game.

Guests

Dan Abramov
Dan Abramov

Transcript

Kent C. Dodds: Hello again everyone. This is your friend Kent C. Dodds and I'm joined by Dan Abramov.

Dan Abramov: Hi there.

Kent C. Dodds: And we are super excited. This is the second show that Dan has been on, on this show that I've not actually released yet, but all of you listening, I have now so there you go. But, yeah, so we're going to be… Last time we talked about Hooks and a really awesome conversation. If you haven't had a chance to listen to that, I suggest that you do. Now we're going to be talking about the future of React and some of the things that React is planning. React is not a done thing. There are still things to be improved. And Dan here… And there are several projects that are at different stages of development right now that maybe we've heard of a lot or maybe we haven't heard of as much.

Kent C. Dodds: I want to dive into some of those things and also think more broadly what is the overarching goal. What's the end game for React? What are we really striving for here? Yeah, to get into that. And, I guess, I just want to start on when you discover that there is something missing in React, what is the process to decide not only that this is a thing that should be solved by React or should be changed in React to solve this problem, but also determine what the solution should be, what's that process there?

Dan Abramov: I think a lot of it is just listening and reading. We get a lot of feedback from everywhere, like from KTOV, from Twitter. From internally, obviously, they have a lot of people using React on Facebook for different kinds of products on different platforms with different constraints. And so, we… I think if you respond to questions and if you look at the problems people run into, and the things that bother them, I think eventually… Or even if you look at the ecosystem solutions where people try to plug some hole in React or work around something that React does that they don't want them to do, I think eventually, you just start noticing common themes between them.

Dan Abramov: It may be that React is missing something or that React is doing something that it shouldn't be doing or that some solutions aren't optimal. And I think in many cases, it's tempting to… Like if I were personally designing a library, I would probably just try to do the smallest possible kind of fix. I would add some API, I don't know. Imagine like data fetching, right? You can see that all their components need to do data fetching but they also need to manage load in states. So maybe should I just build some kind of glowed-in state manager into a library? And if I was personally designing a library, maybe that's what I would do, but luckily, I don't design React.

Dan Abramov: At least I help but I got to work in a team. And I think the approach that the team has been taking to those things, especially as Sebastian… Sebastian Markbage is like a visionary for React and… He has all kinds of funny ideas but his way of working is very interesting. I think what he does is he listens to a lot of feedback and what people ask for, but then he takes a step back and he's like, “Well, why does this problem exist in the first place?" And it's natural, so like you want to do a step back when you're thinking about those solutions, but what's interesting about Sebastian is that he goes turns that backs or like 50 steps back.

Kent C. Dodds: [inaudible 00:04:38] is because of React.

Dan Abramov: Yeah. It is like tradeoffs. Sometimes we do introduce problems. React ensures that the rental result is consistent between the mounts and updates but that can make it more difficult to do animations. Like now, we have to solve the animation problem somehow and so, it's always a tradeoff which problem is worse or which problem is more common. And then sometimes we create a new problem and then you have to plug it too and eventually you solve enough cases that it's good enough, like pretty good. And then they have escape patches for the cases that somehow don't fit that.

Dan Abramov: But I think what's interesting about his way of thinking is that he backtracks very far and sometimes he notices that… like, everybody makes the same assumption and he's like, “No, but why do we even think of it that way? Why don't we think about it differently?” And then that can unlock a whole new path for a solution that is completely different than what anybody else tried. And I think like that's really the spark, like that's the first thing. It's that for every project that we do there's got to be some vision. There's gotta be some spark that is like, “Wait, what if we tried this? Could it solve a whole class of problems?”

Dan Abramov: And so after that we… Usually, then it just goes into a backlog and maybe we do this in a month or maybe we do this in six months or maybe we do this in two years. We have this funny page where it's like a list of code names. There's four projects that don't really exist that are aspirational so some of them are not around, like possible today, but it's like a bank of these ideas and these insights of wouldn't it be cool if we tried this? And then at some point it feels like the place and time is right and it's like maybe we just… this has to be fixed because some other issue made it worse and now… hooks are a good example of that actually.

Dan Abramov: We had the legacy context of the API, the one with a context thought before a create context. There was context tribes and child, context types… not context type but context types. That's legacy one. Consumer is not legacy. That's not part of the newer...

Kent C. Dodds: The new stuff.

Dan Abramov: Right. We had this legacy API that was pretty broken. It was never… It was not documented at first. There were warnings everywhere saying don't use it, it's experimental and is going to fall away but then it was clearly needed. Everybody used it anyway because the feature itself was so valuable even if it was how broken. And so, eventually, we realized we can't fix this existing API but we can make a new one that solves the same problem in a better way that actually works and so that's what the new context of API was.

Dan Abramov: What we released it with this provider-consumer API pair where consumer is a rendered prop, not because the rendered props are fashionable but just because the API design itself needed to be compassable and so we relied on rendered prop to do that. But that kind of made things worse because now that you use rendered pops everywhere, your [inaudible 00:08:22] is just… it's hard to read what's going on and you can't access it from a life cycle. Sebastian has this saying ‘make it worse to make it better' so I think that's what happened with the context of the API. We knew we needed to solve that problem, we solved it.

Dan Abramov: The solution itself introduced another problem and the pain from it was so annoying that it led to hooks which solved all the problems for us. It's just sometimes you need enough pressure on some pain points where you're like, “Okay, actually, we've got to solve this now and we have something that replaces it.” I think that's this the path from the inception of idea to the point where you're like, “Okay, we got to make this happen or we got to at least try it.” And then we'll try it and we duck-foot it to Facebook, we see if that even works. That process can take months, give or take a year, but eventually the project we feel when it's good enough or if...

Dan Abramov: We started by focusing on one use case. We usually would find one team that wants something and we'd work closely with that specific team. And we'd make sure that the API or the solution or whatever satisfies their particular use case and usually that gives us first round of feedback as like, “This doesn't work, this is bad, this is slow.” It is the only way you try it on it. And eventually they were happy and then we are ready to take on more client teams because, maybe, we have two or three teams at Facebook using something. And, eventually, we roll it out internally and more and more people use it.

Dan Abramov: And so once we satisfy three or four teams, we feel like the API is generic enough and we also know it better and we feel more confident about it. And that's when we release it through an open source and that also gives us some feedback, in Alphas and so on, that can lead to some changes. We're just like this fragile graduation process of… it's focusing on one customer then a few more and a few more and then doing this broad better testing and then rolling it out. And that's how we release projects.

Kent C. Dodds: Oh, that's cool. One of the things that I take a great deal of comfort in is knowing that Facebook has 50,000 or more React components. And so anytime…

Dan Abramov: A lot more. I think it's like 90,000.

Kent C. Dodds: Oh my goodness. Wow. My information is out of date. Yeah. But just knowing that there's such a huge amount of React components there, that nothing could possibly happen to React that would make it so hard for me to upgrade because Facebook needs to make it easy to migrate or upgrade or whatever as well. So we're never going to have a, “Here's the new framework situation with React,” which is cool. That said there are cool things that are kind of opt-in that we can get into. And whether it's like… When we had React fiber, that wasn't really an opt-in. It was more like, “All of your existing stuff should hopefully work.”

Kent C. Dodds: And then we have hooks and that's this new opt-in feature. All of your stuff continues to work but now you can use this new feature. I know that there's this project, React fire, which is unfortunate naming with React fiber but there you go. But…

Dan Abramov: That's kind of intentional because like you're not supposed to use those names. Those are just code names. The point over those code names in a large part is because we realized that giving them concrete names like React like this thing, it actually can cause problems because now you're hung up on this idea of, “Oh, this project is like this specific thing.” Whereas actually you don't really know yet until you try to implement and duck-foot and so on. And so we found that code names are really useful because they give us something abstract that we don't have to attach a very specific meaning to and that makes it more obvious when the meaning needs to change.

Dan Abramov: And then eventually when we feel like we're settled on what this project really does, the name just is just obvious how to call it. And then that's when we give it a name and we ship it and then it's just React so it's not a project anymore like React fire or anything. Eventually, even it happens, it's just going to be React. And it's the same with fiber, it's just React 16.

Kent C. Dodds: Yeah. Yeah, that makes a lot of sense. Let's talk about some of these specific projects that you're working on. And I think that's an important insight that you mentioned too because some of these things, in my mind at least, they're really interrelated. We have suspense, we have concurrent mode, we have the new server rendering stuff. I think React fire is in a class of its own with the React DOM specific changes. But, yeah, can you talk with us a little bit about some of these projects that you have in flight and what their goals are a little bit? And maybe start with what stage it's in so we have a good idea of expectations.

Dan Abramov: Yeah. I think from the ones I mentioned… so suspense. Suspense is a difficult one because it's a bit difficult to talk about because it's going to be shipped in stages. And so the first stage, you know like a rocket takes off and then it's like, “[inaudible 00:14:09]?”

Kent C. Dodds: Yeah.

Dan Abramov: We did that already with 6 and release. That includes the suspense component and the lazy wrapper which is we branded suspense for code splitting. But that's just like one possible way to use suspense. The idea of suspense is its declarative loading states. That's what it is. That's really all it is. It's ability for every act component to say, “Hey, I'm not ready to render. I need some whatever. I need to wait for something,” which could be wait for a code, it could be wait for an image to [inaudible 00:14:59] it and decode it. It could be like wait for, I don't know, some data, call or whatever. We don't want to build data fetching in React but we are building this-

Kent C. Dodds: Primitive.

Dan Abramov: -primitive, yeah. Like a way for component to say that it needs something and it's not ready. Because building that into React can actually unlock some very interesting features. And so, one of those features that it unlocks is declarative loading states so now when we try to render a tree we're like, “Oh, this thing is not ready.” What we can do here is we can say, “Okay, we need to show a spinner.” And so usually the way you do that is that you put… right into their component you put [inaudible 00:15:42] is loading then something but then you have to put that logic into like every place where you want to show a spinner.

Dan Abramov: But if you think about it, how do we handle errors? Errors also can happen everywhere but we don't put like error handling logic into every single function. Instead we're like, “Oh, here's a checkpoint. Here's the place where we're ready to handle errors.” And then if anything below throws, we want to catch it. So that's like to try catch... It's like this model of letting some code run but then you can catch it. And you can have nested try catchers so that gives you the granularity. If you have some inner code things, I'm going to run this file system call and then catch an error and I want to handle it in my own way then you can do it.

Dan Abramov: And React 16 applied the same philosophy to our error handling with error boundaries. Error boundaries out from 16, if anywhere in the component, like a component throws, you can put like a [inaudible 00:16:49], like an error boundary or somewhere above it on the tree that says, “If something in my tree fails, I'm going to be full tolerant. I'm going to show you some error message.” Which can be granular so you can put it around specific elements or you could put it at the top level. Usually, you want some granularity, so you put it close to major UI elements. There is actually a great post by Brandon Dale on his blog about how to use arrow boundaries, so check that out.

Dan Abramov: But, anyway, the same philosophy can be applied to loading states as well. You can say like we're rendering something then something's not ready, and then if maybe it's an auto complete widget… And it's silly to put a spinner into the auto complete widget because the whole forum is not really useful if the auto complete widget is not useful. What people usually do is they just don't do call splitting there because it's just too annoying to handle. But if we could put a loading state above, like around the whole forum, and say if anything below is waiting for something, just show the spinner. And you could have like nested ones.

Dan Abramov: That's what suspense really is but for now we're only allowed to use it for lazy loading components and call splitting. But the end game with suspense is that you can use it for everything and then you could use an image component that suspends until the image is ready. And so, you could make sure that if you have an emoji picker, when you pull it out, emojis don't pop in one by one but they just pweeew. That's really the goal of the suspense API. Because it's now declarative, we can understand where things suspend and we can show the right place holder for that.

Dan Abramov: That's one project but suspense for data fetching specifically, there are a bunch of unanswered questions and we're still figuring those out so it's not going to ship in the next couple of months. Hopefully, this year. I don't know yet. We'll see. It's like very active research project right now. And so the other one you mentioned is concurrent mode and I think uncommon mode is… The big picture of concurrent mode is a lot of stuff ties in together there. But really it's about… A part of it is about non-blocking rendering. Currently the way you React works is that if there is an update React will just go ahead, render everything, flush it and like be done with it.

Dan Abramov: But on large component trees that means that while React is going to walk in the tree and doing something and creating DOM notes the main thread is busy and you can handle any events. Even if the event that happened, like if I deleted… if I pressed some button like I don't want to see this tab anymore but this tab already started rendering so you can't switch away from it. It's got to finish rendering so it's blocked. And so what we want to have in React is to make rendering non-blocking so that way I can start doing something but then I feel like, “Oh, I want to do something else,” there is no need to continue and we can just throw that away.

Dan Abramov: And I think it's important to point out that this is not just some work around slow performance of React or something like this. Even if you have some kind of Reactivity system that magically tracks which thing has changed and what is the minimal update… Like in a lot of apps, actually the updates they're not granular. They are very coarse. You switch from one page to another, there is no thousand bindings to an update. It's like you move away one block and then you render a whole new tree and you can't make that faster if you're your own… You got to create those DOM notes and you've got to make those data fetches and stuff like this.

Dan Abramov: And so the question is, can we still make it more efficient and more optimal and to be able to pause in between and if the user wants to do something different we shouldn't like stall the browser? That's really the big picture behind concurrent mode. It's that making this react to this by default because you can make your own rough loop with [inaudible 00:21:25] estimation frame and then try to be smart about updates and idle callbacks. But then it's very hard to orchestrate by yourself because if you try to like progressively load public components by yourself without login you're probably gonna see intermediate states on the screen.

Dan Abramov: You're going to see this tree appearance. If you have a bunch of comments and you try not to block render them, you might be inserting them in idle timeouts and they fill out the page, like all the things jump around then it's really junky. It's not just like UI junky but it causes free flows and lay outs and style recalculation so it's actually… it's worse for performance to keep doing this. What you want to do instead is you want to make the process of preparation, all of these things, non-blocking. But then they want to block when you put it into DOM which, hopefully, should be like an atomic operation-

Kent C. Dodds: Right, yeah. Pretty fast.

Dan Abramov: -to just apply the update. Right. That's really what concurrent mode does. The idea is that you wouldn't even have to manage it except sometimes you would have to give hints to React about which update is urgent and which update can wait a little bit. And some patterns are a little bit different so if you want to take advantage of this behavior you might want to opt-in in a few places. But the general idea is that you write components in the same way but React is just smart about not blocking the browser and instead working together with the browser to give you a good user experience regardless of how fast your computer is.

Dan Abramov: And this is something that you can't even achieve with deep balancing. One common solution is maybe you have an input and then have like a list of items and maybe it's expensive to re-render that list so you're just deep balance. You wait for the input to stop typing and then you update. And so that's the naive solution. That's how you avoid like junk when typing.

Kent C. Dodds: Not a super user experience but at least it's not junky.

Dan Abramov: Yeah, but it is actually. It is junky. If you type something and happen to pause for a second it starts doing something and then you're like you want to delete and it doesn't delete. It's like it's already in the process. So, there's random pickups for you try to do something and then it doesn't work because the deep balance function kicked in and now you're blocked. Really what we want to do is we want to do… And also the other problem is that on the fast computer, you're unnecessarily waiting for that whole second or like whatever your deep balance interval.

Dan Abramov: In concurrent mode the idea is that if your computer is fast enough, you're going to get results as soon as your type but then if it's slow you're not going to block the type and the results are just going to lag behind a little bit.

Kent C. Dodds: Yeah. That's awesome. I think this has interesting implications on our existing code because with suspense that's a new feature, you opt into it by using it. But concurrent mode, if you aren't… I want to say if you're not careful but it's basically if you're not idiomatic, then, you can run into some problems with concurrent mode like realizing that, yes, my function component was called but it actually may not have been rendered yet and so it's going to be called again. And so if you're doing some side effects in there or something, this non-idiomatic stuff, then you could actually run into some problems. Do you want to talk a little bit about that as well?

Dan Abramov: Yeah, I think the most important… I think it's harder to do this mistake with functional components and classes. And that was also a big moderation for hooks, it's just that a lot of those patterns it's just harder to mess them up with hooks than it is with classes. But even with classes, you're not supposed to do side effects and render. That was pretty much day one React 101, but sometimes people do. But I think the biggest change that concurrent mode brings in this sense is that just because a render was called, doesn't mean that the results of it will be flushed immediately.

Dan Abramov: Which is always… so did the case with batching, right? When it also stayed, it doesn't… like in event handler, your [inaudible 00:26:00] state doesn't update immediately and concurrent mode is a stronger version of that, which is actually like more things attached by default. But what, essentially, this means is that even if you're a component gets rendered, the render might get interrupted. So like we may walk to a component, it rendered, like it gave us some turn around, and we walk into children and the user typed something else and maybe this whole tree is now is irrelevant so we'll just throw it away.

Dan Abramov: This is why if you assume that rendering necessarily means the component will be mounted or updated, that assumption might be violated. But then even in classes, if you use life cycles in the intended way, component demount and component to the update are guaranteed to be flushed after it's committed. Those are safe places to do side effects because by that time the DOM is guaranteed to be there or render is more kind of ephemeral, I guess.

Kent C. Dodds: Right. Yeah. And the same would apply to use effect as well.

Dan Abramov: Right.

Kent C. Dodds: Yeah.

Dan Abramov: Right, so don't do side effects in function itself do it within the use effect. Which is more obvious I think because, well, render function is just supposed to return something. Why would you like to side effect in it?

Kent C. Dodds: Yeah. Well, I have been known to do side effects in render before so, yeah… And if you're doing that, there's a better way to do what you're doing, I guess is what we're suggesting. And it's more idiomatic as well. It's not typical that people are going to run into these kinds of problems, but it's definitely something to be aware of. We don't have a ton of time left but what are their projects are you currently working on in the React team? What other things are you excited about?

Dan Abramov: For the past few months, I've been mostly working on, kind of helping… well not fixed folks but just post release maintenance so fixing bugs in hooks, writing documentation. I made this ESN plugin called exhaustive-deps. Sorry, it…

Speaker 1: It's so good. It's so good. It's easy to plug in React techs. It's so good.

Speaker 2: Yeah. And the role is exhaustive-deps. This is the thing to help you build the right mental model around… like if you specify use effect or use callback dependencies argument, this thing will tell you when you're forgetting some of them and it's just this something… It's not even so much the role itself that helps, it helps to understand how to think about them and then you can see the violations yourself. And I think most of the work for me was not even brought into [inaudible 00:29:06] in the past month, but it just figuring out how to think about those patterns and what the best practices are.

Speaker 2: And I think we have a decent idea of what those are and those are encoded into the role itself. I've been focusing on that but I think, personally, I'm most excited about concurrent mode and suspense playing together. It's still like there are still so many unsolved problems there but it also ties into the new server render that Sebastian started working on, that is treeman. You would be able to do a synchronous like data fetching on the server and then stream that out with the data on the client. And then there's…

Kent C. Dodds: What? Okay, let's just make sure that people listening understand the impact of what it is that you just said. That is so cool. Yeah, Will you go ahead and continue? But I just want… If you were coding up while you were listening to this podcast, I want you to stop because this is really, really awesome.

Dan Abramov: I think the other [inaudible 00:30:11] out there think to about it is that… so Sebastian is working on power shell hydration which is, again, this idea… If you take a step back the way server rendering works is not very optimal. Right? Currently if you use a polo which does this double rendering you might not notice it but in practice a render on the server in React currently is synchronous. So you have to do some convoluted way to gather your data dependencies and then you got to send it all as html. Even if you used the NODES stream API, you'll still technically send in…

Kent C. Dodds: [inaudible 00:30:55].

Dan Abramov: You can't pause it, yeah. And so on the client you're like, “You're going to get the whole html first and then you're gonna get all Js, and then you're going to hydrate it at all, which is render your whole app and then it comes interactive." That's not really… If you take a step back and what is the like ideal way you want to do it? First of all you want to flush html. You want to do data fetching on the server because the latency is so low so you want to flush the page in chunks. Maybe you flush the shell of the page first like the layout, then the sidebar or footer, stuff like this, and maybe in the middle there's some kind of shimmer or some loading thing.

Dan Abramov: You can flush that as html and it appears immediately. And then you're going to keep streaming back more things as you resolve the data dependency on the server and you render those components and you stream them in together interleaved with the data that they need on the client and the code. And so you would be able to hydrate it progressively without floating… You don't want to load all the Js just to render something. And so what you could do is when the user starts interacting with the button but that button isn't hydrated yet, but now we know that we need to hydrate this, the components, with this ancestor path first, then that becomes the priority here.

Dan Abramov: And then if we get a resource loading API, so this still… a lot of this is in fonts because it would work so much better with browser support and we're working closely with browser folks on this. So, there are [inaudible 00:32:59] proposals that would make it better. But, ideally, we'd want to say that, “Oh, this thing is important. A user interacted with it give me that code as far as you can.” And then the server could stream in the code and we could hydrate that part of the tree while the rest of the tree is not necessarily hydrated yet. And it's like prioritize loading of everything. And then like suspense could work on the client as well.

Dan Abramov: It's a very integrated picture. And I'm not telling you that it's going to be available anytime soon. It's kind of a longer term thing for… like maybe at the end of this year we'll have something and it's probably going to be a lot more opinionated than you're used to from React because you can't integrate all of those things together if you don't have opinions on how to do certain things. We'll see about how that plays out but the basic building blocks will be like… we won't like hard code any specific data fetching implementation or anything like that. It's more about allowing other opinionated implementations like [inaudible 00:34:05] to take full advantage of that underlying component model.

Dan Abramov: And so, yeah, those are really… I think a lot of those things that are really exciting at the way they interplay together and influence each other and how you can combine them to do things automatically that you just… It was just too much work to do that manually before.

Kent C. Dodds: Mm-Hmm [Affirmative]. Yeah. Well, I'm super stoked about that. I don't do a whole lot of server rendering stuff myself. I use Gatsby and it does that magic stuff. But one thing that I have a question about with the server rendering specifically is it's my impression that React or Facebook doesn't actually use server rendering in its major properties. Maybe it does for some things, I don't know. I'm mostly curious if React doesn't use server rendering, what is the justifiable reason for Facebook to invest in that?

Dan Abramov: I think for a long time it was just an open source thing so we needed a lot of people in the community to care about it and that it's a unique… For a while, it was like a thing you need to react that React could even do this and it seemed like we wanted to empower other companies who invest into React to be able to do this. The incentives for… just that we thought that it's important and we pushed the work on this. But we're also… We've experimented on and off with using server rendering more like Facebook and different parts of timeline and we'll see how it works.

Kent C. Dodds: Yeah. Well, I imagine if you get something like what you were describing working that would be a pretty compelling reason for a company like Facebook to re-work some of the infrastructure to make that a reality so…

Dan Abramov: Yeah, I think the… And this idea with chunks and chunk rendering is influenced by the thing that we use in mechanic and in PHB, this page led architecture which you can Google like page led Facebook or something like this and find the post from 2010 that explains this architecture and why it makes sense. And while the Facebook website might not be the best example because it's just fast over and complicated, there's just so much stuff there, but that's a topic for another post. But the architecture itself is pretty solid and we're trying to…

Dan Abramov: We're trying to combine the things that [inaudible 00:36:51] Facebook about like doing complex silver rendering in hack with the things that they learned in the open source community from products like the next Js, Gatsby and so on. And trying to find what is the most optimal thing that we could do.

Kent C. Dodds: That makes a lot of sense. Cool. There's also React fire. We didn't really talk too much about it and I'll just link people to the get hub issue that you posted back in August about this. But can you just give us an idea of where that is in the stage of development and when we might expect to start seeing some changes there?

Dan Abramov: Yeah. The fire thing is about modernizing React DOM findings so there is a lot of stuff in React DOM that is… I wouldn't say are necessarily outdated but just some design decisions around the event system and around the attribute and property handling, around the web component support, about where we bind to [inaudible 00:38:00] and stuff like this is just pretty old and some of these aren't worth reconsidering. As Sebastian said somewhere that fire is not set in stone. It's more like lava. Don't take the specifics… These are just like specific things that we wanted to look into. These are known problems listed in that e-share but the project itself is…

Dan Abramov: We ordered the prototype version of this and it turned out that some of the event code is actually solving real problems and if you try to remove it then a lot of stuff breaks because actually the browsers are not as consistent as people might think. But it also gave us some new insights about, okay, so if we have this event system and if we think that it's actually valuable, which I think we're starting to think that it is valuable and that it actually solves a bunch of problems, then the problem is, okay, why does everyone pay for it's his weight when they're not using all of those events or if React doesn't even take full advantage of it.

Dan Abramov: The vision for the event system was way broader than whatever, the lockdown version that we're kind of using today. And so the question is then, if we do want to keep that code around can we make it, first of all, easier to extract if you don't use it. And second, for people who actually care about handling events consistently across touch and stylus and mouse and all kinds of inputs and handling gestures like taps, spans, swipes, all this kind of stuff. If people do want to take a consistent API for their sport, what would that API look like and can we offer it as an opt-in a thing that is integrated with React and works really well with it.

Dan Abramov: That's the current exploration. It's just none of this is said on stone. All what I've said might be invalid tomorrow but we're actually getting a little bit excited about the event system… not the current one but we can build a better one. And the things that it could enable that are real problems like product engineers file an entry every day.

Kent C. Dodds: Hmm, very cool. Yeah, I linked to that in the notes so people can take a look and dive in deeper. One thing that I'd asked on that issue that I'm curious about is, and related to another project and I'm just curious about the status of this, is JSX version two. Is that a thing that's being actively worked on? I feel like I've seen that idea tossed around for several years already so do you know what stage of development we're at for that?

Dan Abramov: I think it's in the stage of it's not painful enough to be worth it yet. It's like, I don't know. We could've come up with hooks and not shipped them for a long while until there were some more pressing concerns. And I think it's similar that we… Some of these changes would be nice but it's so much showing for the ecosystem that we need something that would make it worth it or some other kind of clean break that's we can attach it to. It doesn't seem like it's an important thing to do right now but then who knows? Maybe after we ship all of these features we're like, “Okay, maybe it's time to fix JSX.”

Kent C. Dodds: Okay, Cool. To wrap us up a little bit I'd like to ask, now that we have kind of an idea of some of the cool things coming up with React, there's been a history in the React community. Ranked is a framework, React isn't a framework. With some of these changes, it might start to feel like React is really becoming a framework if it wasn't before because now we are handling data fetching and we're doing server rendering and all of this stuff. Is React becoming bigger? Are we just going to put everything into React? And now we have the React to CLI and we have these conventions that we follow, is that the future for React? Or what's the goal? What's the end game for React?

Dan Abramov: I don't find the distinction between a library and a framework very precise or helpful. But I think, in my mind, React has always and will be a library. I think of next Js as a framework and I think that eventually we'd want to… I think it's good when there is a library that solves the core concerns and then there is a framework that lets you leverage the library in one possible opinionated way that is pretty good and that others can create other frameworks that leverage it. I think that's… In terms of what we put into React versus outside of React, we want to keep… we don't want people to be stuck with non-optimal solutions if someone could write a better one. That's why we keep Reacted so pretty lean.

Dan Abramov: But then when we think about… A lot of people use React as just a view layer but React hasn't ever really been a view layer because the notion of a view is very-

Kent C. Dodds: Static.

Dan Abramov: Yeah. People often mean by view is just a mapping between a bit around some inputs and UI but React always been a UI library. It's just not like an MVC library, it's not a web framework, it's a library for build-in user interfaces regardless of your environment and regardless of the broader… Maybe it influences your broader architecture but it's also like its own thing and it cares about this attraction component. And so I think this is why React doesn't have its own routing or its own data fetching because those things are external to this idea of a component.

Dan Abramov: But then on the other hand, if we look at how people use React, you will notice that a lot of components like due data fetching because like it's related, it's a UI concern in a way. And so it may be tempting to say, “Oh, let's just add a get fetched. Let's just make render like return a promise or add get fetch data to render and so on.” But this is like when Sebastian takes like 10 steps back and I think what we realize is that usually if something is related to UI, then, you can split the task that people think of it as a single thing. Like in data fetching, they just think, “Oh, data fetching.” Or it could be like… or like routing.

Dan Abramov: But it's actually… There's usually some lower level primitive that is related to the UI obstruction so in the case of components it's the ability to suspend rendering. It doesn't matter what they wait for, like is it data, or a code or an image or something else, really the language level almost. React is not a language but it behaves a lot like a language and the language level primitive here is that you want to say, “I want to wait for this thing,” and then continue. And then React can be then smart about it in like, “Oh, this component is waiting for something but I can still render all of these components.” And so it gives a React a unique flexibility to do things that you can't just do by putting data fetching aside.

Dan Abramov: As an example, maybe you switch a tab and you're going to… with concurrent mode, we can actually wait a little bit before showing the spinner but we can kick off rendering of header, footer and all of these different elements that are static in a non-blocking way. But then some things might be waiting for data and so they're suspended and then they continue and eventually when it's ready we show the result. And if it's ready fast enough, we don't even show the spinner. We just don't do the transition until the time. And you can't really perceive the difference so it feels like instant.

Dan Abramov: That's really the thing that you get by integrating those UI concerns which is like waiting for things into the library but then pulling out the things that are like they can have different implementations like Apollo, really some kind of simple cash. You can pull those things that actually manage the data and implement them in different ways with different tradeoffs. I think that's really what we… And that's the way we always did it with React. It's that instead of adding applied features that correspond to specific use cases, we tried to find what is the primitive that we can add to the component that can empower everyone to create those specific obstructions that are specific to your use case like routing, data fetching and so on, that all benefit from this shared common denominator that React can efficiently manage a component.

Dan Abramov: And so it's all about empowering and raising the obstruction level so that React and coordinate all these components to work together really well but then you have the freedom to actually do different things from them depending on how you implement them. I think that, for me, the end game is just that we've made components useful enough that it's easy to create really like compelling user experiences that don't freeze your browser, that don't flash a lot of spinners or don't pop elements one by one but instead of show you the whole thing. And so they automate making the UI go to UX and in a way that you could work around it.

Dan Abramov: Like you can do it by yourself manually on a small app but it's impossible to orchestrate a large app to just prepare a beautiful new screen and push it at the right place and so on. And so I think a big part of this is just figuring out the idiomatic solutions so that instead of coding around it in an ad hoc way and adding these hacks to make the user experience nicer in random components instead this is just called works by default. And then if you want a crappy experience you can have [inaudible 00:50:13]. I think that's the end game of React and we're just trying to find a good base obstruction and then make React smart enough to deliver a great user experience.

Kent C. Dodds: Oh, that's so great. I love that goal there. And one thing that I feel like is a really good takeaway for people who are listening is to think of Sebastian's example of what you've described as how you stop and you question all the assumptions. And you say, "Now, we make the assumption that this is a problem and we are assuming that this is the reason that it's a problem but actually it could be this is a more foundational fundamental piece." And I think a lot of people, product engineers or library authors or whatever, could benefit from that type of intentional process. When you have an issue or could have issue where somebody says, “Hey, I'm having this problem, I suggest that we add an additional option to opt out of that or something.”

Kent C. Dodds: Dan, you're smiling. This happens all the time. Instead of giving an additional option, maybe there's another primitive that you could expose or a pattern that you could implement like inversion of control or some other thing that could empower not only solving their problem but also eliminate an entire class of problems, which I think is…

Dan Abramov: I didn't get to a lot of any class of problems which are, hopefully, enough for us.

Kent C. Dodds: Yeah, exactly. Always get to keep that in perspective. All right, cool. Dan, this has been so fantastic. Thank you so much for chatting with me again about the future of React and rethinking what are the goals of React here. I think a lot of people are going to appreciate this episode and pull a lot out of it, so I think you again for giving me your time.

Dan Abramov: Thank you.

Kent C. Dodds: All right. We will see everyone... Well, we won't see everyone, but you'll hear us next week or whenever you listen to the next episode. Thanks. Goodbye.

Sweet episode right?

You will love this one too.

See all episodes

Featured episode

Become Intentional With Your Time With Scott Hanselman

Season 1 Episode 11 — 31:47
Scott Hanselman