Video details

Nir Kaufman - The beauty and the beast: custom renderers in React | ReactNext2021


Israel's Annual React & React Native conference
The beauty and the beast: custom renderers in React
Nir Kaufman Front-end Guild Lead @NEXT Insurance
In a long-time relationship with React as a developer, author, consultant, and trainer. Google developer expert in Web technologies, Vegan (but nice), electronic music producer, and sound designer at night.


2021 today, if you've seen my title, I'm going to talk about the Beauty and the Beast or Renderers in React. There's going to be light talk. I don't want to get too deep into technical details because it's late. I do want us to have fun and do something a little bit exciting or to bring back the excitement to React. But first of all, I'm very happy to be here in person in this conference. I think it's amazing that during these times, but let us not forget that we are not safe yet. It's not over yet. Every day now, developers choose to angular on top of React, but it's getting better. It's getting better. Hope for better days. I work at Next Insurance. We've got a booth out there after the talks come over, check us out. Maybe you win a MacBook Pro. Yeah, that's my picture. But it was like a year ago. So I'm the same person, same face, maybe. At least with the Madonna. I'm using React for, I think, something like five or six years. So I can say I'm in a longer relationship with this library. And like I said at the beginning, the purpose of this talk is to get us excited again. Personally, I thought about what I'm going to talk in decision, maybe state management or style component or something like this. But then I told to myself near and I answered, what? Don't do it. React is the library for creating user interfaces. And one of the things that I had a chance to talk about this topic of being a front end developer these days, because React is not only for web like, most of us obviously know we can run React on the server side. We can render React components natively on devices. We've got React VR. And I find it very exciting to talk about the different types of UI user interfaces which have to be graphical user interfaces. Like, are you a front end developer if you're building voice actions for a voice activated device? What about brain computers? What about different types of UI? So this world of being a UI engineer UI developer is changing. And personally, today I want to remind us all why React is relevant. I think more than ever, when you start to expand your UI development skills to other areas. Declarative UI definition. Yeah, we all heard about it. But I want to, just as a reminder to spend just a minute about React. So let's look at some code, or you want to go over with the slides. Who wants to see some code, obviously. So let's open up this code, close it and open a professional ID. Microsoft is not sponsoring this event now. I want to tackle guys index. Js. All right, so just as a quick reminder for all of us, if I'm going to cancel log my app component and I'm going to run it as a function, all right, I'm not going to use JSX, and I move back to the browser. Let's refresh. And what we've got here, like most of us know, but like I said before, it's going to be a gentle reminder. The React package, the React library is nothing more than a set of utilities that help us to build a tree which contains objects and functions, which means that I can take this object, I can take React, and I can render it wherever I want. Which means that if you look into React source code, you won't find any piece of code related to the Dom, to the browser. You won't find document, create element. You won't even find the implementation for React hooks, you won't find use state, you won't find useref. So the React library is very focused. And I describe React as just a set of utilities to build, to describe a dynamic tree. Gentle reminder. Cool. So all the heavy lifting of what I'm going to do with this tree happen in the render. Most of the time, we build React application for the browser. So we just take it as a fact. We generate a project, we've got the index JS, we use React Dom, we're going to render it to the Dom, and we've got it up. And that's it. Maybe React native React. Bring us a tree. And the most important piece on this tree of object is this one. The type. The type is a string. It's just a plain string. It's got no meaning at all. I can write whatever I like there. I can specify that I want to create a UI interface, and the type is going to be, I don't know, George Bob, DIVS, pen, text container, whatever. I like the library that cares about this simple string is the renderer. If you're working with React, Renderer, React, Dom, renderer, and you render your app, you should use strings, which describe reserved words, which is part of HTML. Cool. You are not surprised. Hopefully. What is George? Let's build a George renderer and see what happens. All right, back to the slides. So which type are we creating? It doesn't have any meaning. We're going to create strings, and we're going to give these strings the meaning about where all the heavy lifting happens in React. Like I told you before, that's not going to happen inside the React package. Everything is located inside React Dom. But the great news about it, that Facebook exposed. Let me jump into an empty file. Facebook exposes a library called React Reconciler, which looks like this. Can you do this? Yes. Save me some typos. What is React Reconciler and why do I care about it? Because React Reconciler, that's the diff algorithm. That's where the heavy lifting of React actually happened. And it's exposed to us as a very simple, well defined interface that enable us as developer to decide how we want to render React tree. So what we're going to do right now together is build a React renderer from scratch, throw away React Dom, try to render some Dome elements for fun and then try to give it a twist. So let's start with this. I created an empty file. I export an object which got a simple method called render. We are all familiar with this render. You should provide component, your root component, and the container which is the domain in most cases. And this reconciler, let me create it. It's going to look like this and it's going to be equals to reconciler function. And here I'm going to provide an object called host configuration. I created the boilerplate and I published it on GitHub. Gist. So if you like to play with it, you can grab it. I'm going to share the links with you, but basically it's going to look like this. What is this host configuration object? It's a set of methods and we should fill the empty spaces basically. And it's straightforward. And currently I'm not using TypeScript, but even with plain JavaScript, you can understand from the methods names what they're going to do. So all I need to do in order to take the output of React, which is a plain JavaScript, objects with type which is a plain string, and do something interesting with it. It just implements these methods and even not all of them. Let me show you what I mean. First of all, I've got this reconciler, I've got this host config. I created a reconciler passing this host configuration and I exposed the render component that use this reconciliation to create a container and update the container. And now I can come back here and instead of using React Dom, I can use React. I call it react. Synth. So if I go back to the browser, hopefully. All right, render is not exported from React synth. It's just a matter of the default. Yes, you're right. I should do something like this now. Yeah, cool. All right, nothing. But now I've got all the boilerplate I need to start implement my own renderer. So back to this host configuration. Like the name suggest. React. Give me some kind of clear interface to describe what's going to be my host platform, what's going to be the target. I want to do a quick console log for create instance so you all can see it. Let's do this. I'm going to console log, type and props. I'm going to go back to the browser and look at this. The method create instance is being called by the render. Provide us the minimal information that I need in order to decide how I want to create whatever I want to create. Now I can take this Divh one header span which is part of the HTML syntax and just use few pieces of code, something like this. I can go ahead and create a Dome element. So like document, create element, pass the type and that's going to be my Dom element and I can return it. And now I created a renderer that's going to create a Dom element. That's not going to work yet because there are some basic methods that I need to provide. For example, how do I deal with texts? So if I created Dom renderer, it's going to be document, create text, node, and I'm going to provide a text. And how I'm going to build the tree, how I'm going to append children. So again, I'm walking against the Dome that's going to be append. Same for. Is there any other append here? I don't think so. Here we go. Parent instance, a penchild, a penchild to container. And I think that basically that's it. Let's see. Yeah. All right. So it's easy as that. Just to fill these empty spaces, take this plain tree of objects and do whatever I want with it. Now, this demo, I think, shows how simple it is, how straightforward it is. But it's not too excited because, again, that's the Dom renderer. We just add a few lines of code and we can see Dome elements. First of all, that's not enough. I just want to show you that because all you've got is displaying objects which contain a bunch of props, it's easy as that. To support CSS, for example, I can take the props. I can check if I've got a class name, and if I've got a class name on the props, I can take my Dom element and assign it to class name. All right. And our supporting CESUs. So that's the basic. That's the foundation. You are not excited at all, which is you're not supposed to be excited. But just out of curiosity, who's seen this for the first time just to know. All right, cool. So at least, like, I don't know, 40%. So I'm happy that we got us up and running. All right, I want to introduce you now that you're familiar with this interface, before we're going to add some code, this repo called awesome React renderer, which basically doing the exact same thing that I just did training this file, custom renderer, implement all the important methods. Take the tree of objects, but the output can be whatever you want. Now, there is a very impressive set of renderers right here for hardware, for playing sound, for creating email templates. I think they cover almost everything, but you can always think about wait a second, react. Give me a dynamic tree of objects. What else can I do with it? Give me the react. Reconciler doing all the heavy lifting of this diff algorithm. What other things? I can benefit from having a very fast diff algorithm, maybe. I don't know. I want to use this def algorithm and JSX to describe an insurance policy and find the differences between one policy to another and get some kind of results. I mean, I can take it to the business side of things, highly encourage you to check out this repo play with it. It's easy as just change the renderer and use different strings. I mean, depending on the renderer that you're aiming for. Now let's do something fun. Raise your hand. Who's had the chance to listen to his app? Have you ever heard the Dome playing music for you or just me working too hard? All right, let's start to do something fun. I'm going to use a library called Tone. Js tonjs is a library that use the Web Audio API in the browser and can produce some from scratch. So let's do this. Now, what I'm going to do, I'm going to take a set of notes, I'm going to create an object, and I'm going to map Dome elements to music notation. If you're not a musician, and that's the first time you sing this, each one of these letters, A-B-C-D. It's basically Dome for solacey. So I'm mapping the Dom elements to a specific music notation so I can do something interesting with it. Thank you. Next, I'm going to expose on the window just because it's a live demo and I don't want to start creating a bunch of us. Just show you something nice. I'm going to expose on the window a play method and a stop method. Now, I'm going to come here to the most important function inside the source configuration called the create instance. And every time I create a Dom element, I'm going to push to my notes array. Let's go to my available notes and push the type. So basically, I'm going to end up with an array of musical notes. I should use this map. Where is it? I lost my way. Here you go. Yeah. All right. So basically what I'm doing right now, I'm mapping Dom elements to musical notes, and let's take a quick look on our app. So currently I've got the Div, a header and H one and another closing tag. And here I've got a span and let me hit another span. And if everything was okay, let's try to listen to our Dom. Let's do something like this play. Let's try to create some music. I just added a diversary. All right. Just a waste of time, but. Well, that's me. I don't have any social life, friends or habits. I can create don't for music. And that's the purpose of this session, guys. To inspire you. For you. Yeah. So what I'm trying to say. All right. The purpose of this quick demo is, first of all, to get you excited again, to try to encourage you to explore the world of custom renderers, to use your imagination. Like you just said, let's take a very famous musical creations and try to create Dome out of it and see what's going to happen with it. Maybe video art. Whatever you want to do, react is super relevant because the way react build, they expose to us a simple function, a single point of interaction is called the reconciliation and all we need to do is just fill up the empty spaces, tell our renderer everything he needs to know about our host platform and basically that's it. So hopefully you got excited again. First of all, thank you. Second of all I'm going to use this last three minutes to say thank you for all the people that I met today. That gives me a very productive feedback about my meetup group and invite all the rest of you to join my meetup group which is all about doing stuff like this while we drinking for fun. I can't use to buy my new book that I just published. It's a romantic exploration of CSS and if you buy this book, every dollar that you spend I'm going to spend $2 to support PHP developers. That's looking for a job because it's 2022 and we're all doing JavaScript. If you want to keep in touch you can find everything about me because I have zero Privacy on this simple website I'm going to publish the links, the slides. If you want to ask some questions or dig a little bit deeper you can find me at the next insurance booth at the end and again the quinoa people. Good luck and thank you very much.