Making The DOM Declarative - Michael Jackson @ ReactNYC

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
that that dishes sound back here gave me like a like like a flashback to when I was when I was 16 and I worked at a ice cream parlor and I was bussing tables okay and the place was packed it was like a Friday night place was packed packed packed packed and I was busting the tables and I had this cart with like three levels on it right and you would go and you would bust the table and you would like pick up all the glasses and put them in the bin and then when the cart was full you'd go and take it back and they'd wash the dishes you know and my cart was full I mean it was like full full but I saw one last table on the other side of the room and I was like ah you know what I'm gonna just gonna go bust that one last table and and then I'll go back to the dishwasher okay so I went and I like zigzag through all these people got to this one table put my cart there turned in and to get that you know the things off the table and all of a sudden out of the corner of my eye I see the coal cart like shifting and you know they were like these like those big like Sunday glasses and things you know like on the top and just thrashing out like the whole thing just crashed on the floor it was a it was a huge like it was something out of a movie I swear it was this huge crash in this big place that on a Friday night was like jumping and like like conversation like it was very very loud was silent like silent and everybody was looking at me like usually like somebody collapsed everybody felt so terrible that nobody even wanted to clap and I looked at the owner and the owner was like this old surly like ex-navy dude and he had like tattoos on both of his arms and you know and and he was about to like swear up a storm right in front of all of his customers and one of the waiters and Stoops down and he picks up a wheel off the ground and he goes huh loose wheel one of the wheels had fallen loose from the cart those three words saved my life in that moment he goes huh loose wheel so now whenever I hear dishes crashing I'm like oh no I'm back there now I'm back there again the dishes are crashing down no but anyway it's it's thank you for bearing with me my stories my name is Michael Jackson yes feel free to say whatever you want I've heard it all before actually somebody told me a new one the other day but anyway I'll spare you so I am here from California I gotta say I love visiting New York City loved loved loved visiting New York City it's probably a favorite place to visit here in these continental United States I wonder sometimes if people who live here how know how cool it is there's like the people the food the culture I mean it's just everything it's it's so cool about New York City in fact I brought I brought my wife here last year for Christmas I live in Carlsbad California with with my wife and four children two boys and two girls the oldest is 11 the youngest is two so we are quite a full house obviously the one who's two is the boss right now if any of you know who've had a two-year-old that's how it works um okay so uh so I so I trained on on react and I work on react code professionally actually I loved it so much I quit my job and I made it my job and so we so I am half of a company called react training my business partner is Ryan Florence Ryan was here just a couple months ago actually at at the meetup that you all had at Shopify or not Shopify it was Spotify that's what happens and all the companies change their names if I APPA fie anyways Spotify anyway so so yeah so he and I were react training and we we basically do training full-time and then we work on open source code in the other time that we get so the the workshops that we do kind of fund the the training that we do I'm in New York actually this week doing a training workshop with we work and so if you're interested in any react training we'd love to come and talk to you chances are if you're doing react you're probably using something that we built so we'd be happy to come in and teach you about it and tell you how to use it okay so that's so that's a little bit about me and I just thought so tonight I wanted to talk a little bit about let me close this here I wanted to talk about what it means to be like declarative okay and in what it means you know when somebody says that react is declarative um what does that give us what power does it give us and why is that cool and hopefully you know we can have some sort of you know back and forth this is just you know this is a meet-up so I want to just kind of throw some ideas out there and see if they stick and we'd love to get your feedback on them as well I think I may have how many people here saw the talk that I did a couple months ago about render props okay how many people hated that talk and hated me for giving that talk feel free it's okay it kind of kind of rustled some feathers we're gonna be using some render props tonight so if it makes you really mad you know just cover your eyes or something or close your ears okay so uh so let's talk but but you know before we talk about the declarative stuff I think it's useful to just kind of back step one step and just say okay so how did we use to do stuff how did we use to write apps before we started using react and then we can contrast that with the way that we currently write stuff because I think that's that's really helpful to see where we came from in order to understand why what we have is so cool so so here's our old friend yeah yeah how many how many people thought they were gonna come to a react meetup in 2017 that was the first line of code they were gonna see right what is this guy he's crazy okay so um remember this you're like prefix your variables with the with the dollar sign so let's make a little app here let's put a let's put a an h1 so I'm gonna have a list of Sporting Goods and we'll put an O L in there and we'll append that to the document body okay let's see let me save this and then I'll go back here and make sure that it's actually working okay I'm gonna put this over here on the right I put this over here on the left so we can see them both at the same time okay all right so let's say that we've got a list of you know inventory products basically in our store maybe I've got a baseball bat maybe I've got a basketball any Knicks fans in here no not one it's okay don't be shy okay yeah I was I was pretty crazy game the other night so let's see and we've got a tennis racket tennis racket okay and so if we wanted to put all of these things you know we wanted to show a list of the inventory on our store we might do something like go ahead and grab that Oh L and then so I might do something like inventory dot for each item and then go and grab my o L and say hey just append a new list item guarantee you weren't using back ticks the last time you were using jQuery okay so there we go so that will put everything in our what I'm doing in our list okay and I'm so productive with jQuery why did I ever leave it this is great okay so so we've got the app up here already we've got our list going and now let's maybe maybe let's put in like a form so app append let's append a we'll have a form here and that and we'll have an input in the form and it will be I don't know the the new item so we'll just call that give it a name of item and then when we submit that form you weren't using arrow functions either okay so when we submit that form here we're gonna get an event object and we'll just event treatment default on that and so basically what we're gonna do is we're gonna use this form to add something new to the list okay let's just let's say grab the values I'm gonna serialize the form let me go in and pull in my serialize form library uh-huh okay so I'm gonna serialize the form I'm gonna grab out that value and let's just log it right now values dot item and let's see if we can get that to logout let's move this to the wrong one let's move it to the bottom okay so if I wanted to add like a bowling ball okay so we'll get that here one other thing that we're gonna do is I'm going to clear the form event that target that reset okay so so if I were gonna add this item to the list right it's one thing to render a static list if I'm going to add this item to the list you might think okay well we've got a list of inventory why don't you just inventory dot push that item right inventory I'll push that item and then and then we'll just go and put you know all of the inventory and the list so let's see I've got a bowling ball oh I forgot right so so essentially what I need to do is first I need to go and like remove the stuff that already exists in the list so I'll say inventory dot I don't even remember is there something for like empty it let's see let's roll the jQuery dice and see bowling ball no okay that's not a thing oh I could HTML it yeah there we go oh come on you did this you know you did this be like nothing I never did that that is beneath me inventory dot HTML is not a function oh I need to do it on the a/o thank you thank you thank you people are like this guy how long do we have to stay here uh okay all right I'm gonna try it one more time whoo thank you that is my talk and we never should have left dickory thank you I'll be around all week right so so so so what happened here and what's going on here right um there's there's kind of a little bit of like there's a little bit of time involved here all right um and and you know I kind of introduced that little little bug on purpose right but there's you know there's I have to think okay so have I rendered this list before and if I have then I should probably empty it out before I go and and just like reopen to all of these items right this is probably also the least possible efficient way to do this right some of you are thinking why don't you just put one new item in the list right well in that case like now I have to worry about well you know is there a list in the page at all like what we you know what have I what work have I already done because now I need to do some more work so what work has already been done for me have these you know has this for example this append already been done is what I'm asking right so I've got like this this very sort of imperative way right and this is how we used to do things is is we used to think very very imperative ly about building our apps and we would go and grab an object or grab some some piece of Dom and then we would go and call methods on it and say okay now I've got the div now go empty it now I've got the div now I append this and append that whole thing to the body now I've got some items and append them to the list right so so this is kind of how we used to do things is that we used to think about building apps let's rebuild this app let's just rebuild this app with react okay oh yeah I've got import statements no none of that require commonjs garbage here we go okay so so if I had like a let's see I'll call it a oh no I'm gonna use a pure function no no I'm gonna use an app extends react dot component we okay I've got my render function here I just want to grab some of this HTML cuz I don't have to type out all that stuff again return that a div will put the form in there what else do we have we basically had the h1 basically have these things right here there we go we'll close this here okay all right so let's get react Dom - okay so react Dom dot render my app into I'll just get an element out of the page up I could have just put it in the body - but then react complains so let's say the starting state here is going to be the inventory I think we still have that variable hanging around somewhere up here just grab that real quick put it down here actually I'll just put it right in line okay and now I could say you know something like that I'll say let's see so this dot state dot inventory dot map will have an item here and then we'll say something like what did we what did we say we're going to do oh yeah we're just going to put them all in a bunch of list items so then we'll have item or key we could just use item for that for now all right all right rewriting stuff with react all right so now so um so first of all I want you to notice something right where are the append calls nowhere right like you could say that we've got some imperative code here which was render the app right but but if you've been using react you'll know that actually that call is idempotent which means like if you call it twice with the exact same you know element class and the exact same node well it's just going to update the one that exists there already instead of like rear-end earning the whole thing so even that's kind of safe as far as you know impaired stuff goes but then we don't have any real like append calls here or remove calls let's see what happens so let's set up an on submit handler here on the forum okay and I'm actually gonna reuse a lot of this stuff so I'm gonna just copy all this stuff handles submit it's gonna be an event handler okay prevent default there get all of the values so this is going to be instead of just an inventory dot push we're gonna say this not set state with the inventory is going the new inventory basically I'll just use a state callback here I always get a little uncomfortable whenever I'm like setting state based on previous state and I'm not using the callback form so I'll just say state dot inventory dot can cat with this new with this new item right so so values item so okay so gone is the push and then what happens to all of this sort of imperative code as well just kind of disappears right we know from working with react that you know these are pens and and the whole like okay we need to reset the existing HTML that's there we know that that stuff just kind of goes away okay does anybody see an error in my code let's see if it works oh geez serialize form is not defined you're all fired import serialize form from form serialized that's not confusing alright let's try this again bowling ball go yes okay so so we've lost all of the all of the append calls right all of the like here go and do this now to the element going append this go in and empty it empty out the other items okay now put in the new ones all of that code we left it behind when we move to react we now no longer have this this imperative model where we're grabbing elements and we tell the browser what to do with those elements we now just say the page looks like this okay given my current state given what I know about the state of the world this is what the page looks like and react it's your job to make it so to make it happen right and we hope that it's efficient at doing what it does but but honestly that's not even in our that's not even our job anymore we just we just tell react what the Dom should look like hey so this is what I mean by by declarative programming and instead of going to the elements and manipulating them and manipulating their contents I just declare what the contents are or what the contents should be and then I let react do the actual updating of the page right and so sometimes I I compare this to kind of like cruise control for your car right like cruise control is you know is the declarative interface I want to go 80 miles an hour go I don't have to push up and down on the gas to tell my car to go 80 miles an hour right III just I just declare it once and it's done so so given the fact that react gives us this nice declarative model for the Dom could we use that same declarative model in other places like in our own api's for example in the in the code that we write okay so let me let me let me show you another like example so what if we had an app here I'm gonna get rid of our our little sporting goods app real quick let's see so if I had an app here that was basically like as soon as component did mount fires I'm gonna track basically the geolocation okay of my my app okay so I'm gonna say what is it what does the API navigator dot geo location dot watch position and then I'll just say position thank you some people saw that type when they're like I can't wait until his code blows up you sir we're very kind you were like ah there's a typo there thank you okay so so what I'm gonna do is I'm gonna watch the position and then just console that log let's see if that even that even works okay so I got my I got my position here I got my coordinates good let me set how about I'll keep some stayed around and I'll say I'll call it lat and that's null and I'll call it long and that's null and and then whenever my position changes I'll say this set state lat is going to be position dot chords dot like it calls it latitude latitude it long is gonna be position dot chords dot long longitude English I don't know how anybody learns it okay latitude and longitude all right so let's see that and then basically let's come back here and let's say let's see your position is this dot state dot long or sorry lat or and then this dot state dot long or some dots let's see okay cool right so so this is you could say well that's uh you know this is kind of an imperative API right just like you know append which you know jquery's append is obviously just you know sugar for like appendchild right or remove child or whatever that HTML function was just sugar for inner edge tml equals right so so that was you know those were imperative sort of operations that we're doing well here we've got another like imperative operation right I'm calling this watch position API and you might say okay well so how would how would you share this like with somebody else who's on your team right think about this what if what if I had so this is some behavior essentially which is watch the location watch the position and then somebody else says hey Michael I saw you built that cool app that liked where I was you know I could watch the position of somebody walking around I need to do that in my app - can you share that code with me at which point I would have to say something like yeah yeah sure no problem all you got to do is say navigator dot geo location don't watch position and then as the position changes then you can set the state oh and by the way you're gonna need some state right so so basically everything that's up here is is boilerplate right so it's it's boilerplate which means like I should have a good way to share it and it's also kind of like like imperative code that's going on right so I think some of you might know what's coming what if we took all this stuff and we just put it in a Geo position component and we'll just just copy and paste all that stuff up there and what does a Geo position component render well we could just we could just tell it what to render like I could render a geo position component here and I could give it a render prop we'll get back some state okay so now instead of living in my local state this stuff lives in lives in the state of a a component that I can use right so it gets a it returns this dot props dot render if you've never seen this technique before you probably want to go back and watch my render props talk that I gave him Phoenix a couple months ago okay so so basically well all we're gonna do is we're gonna take this this imperative API okay and we're gonna create our own sort of declarative abstraction for it okay and all we're doing here is we're just following Reax example right reacts said hey there's a bunch of imperative Dom stuff appendchild remove child set attribute add event listener write all of that imperative stuff that you used to have to do when you're building your jQuery apps we're gonna do that stuff for you so you can just declare what the state of the world is you can just declare what the UI looks like and now what we're doing is we're following that example and we're saying hey you know what there's more there's more imperative API out there there's stuff like this geolocation watch position right that's an imperative API I wish I had a declarative API to sort of sort of paper over that you know to sort of smooth that over so and so it makes it shareable but it also makes it you know declarative so I can look at this render method and I can see aha we are doing something with the with the geo position here okay what other kinds of things could we use this for so I've actually got a I actually did this with we built a component a while back called react training react media we did this with with like media queries right so you render uh sorry you render a media component you give it a query which is basically just like a CSS query string right what's the imperative API that were that we're glossing over here does anybody know it's the match media API window dot match media any any browser that ships with support for media queries and CSS also has an imperative JavaScript API called match media you basically say window match media and then you get this listener thing and then you have to set up your functions on the listener and then when they get called then you set state right all of that stuff all of that imperative code that that I just mentioned all of its boilerplate if you want to use the match media stuff in your react app so what we did is we say okay let's wrap it up into a media component you just give it a query and then we'll tell you when when that value of those queries change okay so in this case we're using the children prop instead of a render prop it's not named render it's just naming children but it's the same kind of idea okay one more example that I wanted to show I think I've still got just a little bit of time is the where was it so it was here let me see if I can get this get this working so I have a little chat app here finding the exercise here in the solution here come on don't fail me connection come on there we go okay that was me earlier at the so I got this little I've got this little chat app and Ryan is right now in Dallas it was kind of funny because he was giving this same workshop in Dallas and I was here in New York and we were chatting back and forth for a while so the people in Dallas are saying hello NYC so we have this little we have this little chat app right and if you'll notice something about this chat app it's it's fine but it's it's also kind of a little annoying because it doesn't actually scroll for us right so so you know it's what do you think about it that's like the scroll position that's you know in managing that that's a very imperative process like could we make that could we make something like that declarative okay that's a that's another dumb thing that we have to do sometimes right in the dome so let's take a look at my chat component here real quick so I've got I've got some state here which is just basically off so I oft when I log in we just off with github and then I've just got an array of these messages and then as I get new messages I set state with those so that's basically all there is to that that piece of it so so this messages array is just going to keep growing and then in my render method I pull them out of state and then I group them using a reduce yeah okay now it's it's actually way more complicated than it needs to be and then and then I just map over those message groups and I and I display them here right so so the thing that I'm using here to put them in is I'm just putting them in a in a div with class name messages and that's my that's my scroller if I if I we that come from a view source who've you source these days lame yeah exactly Jared no I'm just teasing view source is how I learned to program darn it okay so let's see I want to inspect this thing not really that thing but its parent but it's too hard to come on geez oh this thing is way up Kylie okay that thing has got overflow:auto okay so that's my scroller that div with class equals messages that's the thing that's that's providing the scroll behavior right could I manage that scroll behavior with a component ah thank you just don't say anything mean please yes okay could I manage that could I manage that scroll position with a component with it what if instead of a div what if I had something like a pin to bottom what is it pin the bottom what does I even do so let's make a component here called a pin to bottom and now remember the goal of this is to make some imperative behavior declarative okay um you know what I should have done before my pin to bottom sorry I'm rushing ahead just one just a little bit sorry sorry I'm gonna leave this as a div for just one second and I'm just gonna do this in the component first so maybe I could have like a ref on this thing and I could be like the ref is the scroller and then on on component did update basically what I can say is this dot refs I'll say the node is this dot ref scroller okay so that's how I get a reference to the node and then I'll say no to scroll top is node dot scroll height okay okay so here we go so now when I say stuff say stuff again it Scrolls problem solved right I mean pretty much right until somebody comes along and they say indeed no it is not so somebody comes along and says hey you know that auto-scrolling thing that pinned the bottom thing that you were doing that was totally cool can I use that in my app too and I'm like yeah sure just write this little bit of imperative code at which point you say oh no dude we started using react like six months ago why are you still writing imperative code you're bringing me down right I want a way to do that declaratively right here so so and plus I got this graph like that's ridiculous there's rap on things I need a component to do this okay all right fine we'll give you a pin the bottom component get rid of the ref here and we're gonna basically just take this this imperative code we're gonna tuck it away inside our pin to bottom so what is a pin to bottom a pin to bottom is he div essentially right it's replacing a div so it is a div we're gonna pass along all of this stop props we'll put our Ref back here so you can get the note this dot node okay so now I can share its share a bowl now see so if you want this pin to bottom behavior what's it gonna say okay long oh alright okay so so so the pin the bottom is shareable now and it's also it also communicates like some you know kind of intent right oh I see what this is it's not just like a div that Scrolls it's one of those things that that's pinned at the bottom right well in this case the pin to the bottom might not actually be what we want right what if I scroll back say something else and I'm like oh what did that that one guy say oh yes this is very very interesting please say something else Oh what what oh I just I totally lost the context let me try it again I'm gonna scroll back here somebody said something super ah stop it right basically after every single update now I'm just thrown right to the bottom of the chat right isn't that super lame what would be nicer well maybe a notification maybe maybe what we could do is we could infer whether or not they wanted that behavior by how far down they were scrolled right so if I'm scrolled all the way down you can infer he wants to see the latest messages he wants us to auto automatically scroll the view right if I'm not don't do that I scrolled back for a reason right I wanted to go look at some older message in the chat okay um that's now that's what we're describing here it's kind of a complex behavior wouldn't you say like if I'm scroll to the bottom automatically scroll if I'm scroll back don't scroll it let's try this here so see so instead of a pin to bottom what I want is more like a completely non descriptive name like smart scroller yeah like a smartphone like what does that mean I don't know it's a smart phone all right okay so so I've got a smart scroller here now so how could we model how can we model this behavior basically what I'm gonna do is I'm going to put an on scroll on this thing okay so I'm gonna have a scroll handler handle the scroll and what I basically want to say is look uh if if they're scrolled all the way to the bottom then don't automatically scroll otherwise or sorry then automatically scroll otherwise leave it okay so I need to calculate let's see I'll say off versus a scroll top scroll height equals this dot node also get the offset height Oh math all right so let's see so const let's say the distance to the bottom of the screen or distance distance from the bottom is going to be so the scroll top is how many pixels are invisible above so the scroll height is the total scrollable height of the thing so it's going to be scroll height minus the scroll top plus the offset height in other words how many pixels do we have left to scroll before this thing is actually at the bottom scroll top plus the offset height okay so I'm gonna say I want to automatically scroll if the distance from the bottom is less than 10 so if they scroll all the way down and they're within ten pixels of the bottom then then we're going to automatically scroll okay component did mount will initialize that value to true I'm actually going to take this code and I'm going to put it in a method called scroll to bottom because I want to reuse it in both the component did mount and I'm going to reuse it in component it update but only if this dot Auto is scroll you see what I'm saying so here's where I'm making the decision right I'm saying as they scroll listen to that scrolling assuming I've done the math right from bottom there we go so let's see let me bust out the console.log here okay yeah so it's big okay so it's small there okay good okay so so this thing should automatically be scrolling when I'm when I'm already scrolled to the bottom otherwise if I'm scrolled back up don't auto scroll for me when you get an update so if I'm so if I'm fine down here should scroll other wise not should now not now kind of interesting right to think about and night I mean that's it thank you Matt that's a fairly complex behavior right that's a fairly complex imperative procedure right doing the math you know doing the doing the scrolling setting the scroll top right this is a complex imperative procedure behavior that we can now share because we just wrapped it up in a component and made it made it declarative so if you want that same behavior all you got to do is render a smart scroller and you're good to go I was stoked to see that Jared actually launched his react react FNS project tonight because that was something that we were this is something that we were talking about at dinner just like a month ago where he's basically taken a bunch of these imperative API is like geolocation you know media queries Network stuff it's a pretty project that we've been working on as well Ryan Florence did you know he did a react Idol a couple months ago react Network a couple months ago obviously I've done react media so it's a it's a problem that it's like why are we still doing things imperative lis right when we're in the browser we should we should have learned from react by now we should be doing things declaratively instead of imperative Li and so that is kind of the principle that I wanted to talk about and thank you so much for having me two questions okay yeah quick one sorry I went over yeah yeah so we can I mean yeah we could just I'll just tell you how how I might handle that so I Know Who I am here in the parent I've got off right and so I could do something like hey only scroll when you know the off is my off dot ID or whatever right I could pass in a prop here and basically say basically configure this thing this way and say hey there's there's a special ID that I don't want you to actually scroll on ya scroll air needs to know about the data end up in that situation yep so it would be like a message scroller or something like that right yeah another question one thing I knew is when switching to reaction router for yeah was just like there used to be cross that you had that and then when I want to get this in behavior react router for when it dropped some of those things I had to write a whole lot more extension yeah use that equality of this program yeah yeah so the question is I went to rector for the previous versions did stuff for me that version for doesn't you know is that in general the the type of thing that I'm gonna have to do when I when I go this route and from what I've can tell yes like that's that's kind of how it goes right if previous diversion for react router was solving a lot more problems than we ever intended to solve we had code in there for doing things like code splitting you know which you know and and hot reloading like we had API and ways to manage that stuff when you know react router is not a tool for code splitting react router is not a tool for hot reloading your routes you know it really is just a tool for you know updating the UI as the location changes and so we we reduced our scope a little bit and said this we're just going to focus in on this one problem we're just going to give you a couple of components but you know like I said like scrolling you know is a is a is a problem that you can totally solve with a component you know inside one of your routes for example so so yeah in general yes I think and we could talk more about it later but in general yes I would say giving components like smaller responsibilities means you probably have a few more components to actually deal with means you're you you may have to end up writing some more of your stuff good news over to more of your own stuff good news is whenever you get lower-level bits like you don't lose the ability to do higher level things you can just put a bunch of them together in a component and now you've got your higher-level behavior again which is exactly what we've done with like it's kind of what Jared was doing with like the server-side routing stuff with reactor 4 you know we didn't take that away it's a little more work now but we didn't take that away you can do the same thing with code splitting and reactor out or force so so there's there's some trade-offs yeah we we have a smaller scope we're solving fewer problems but you can use composition to solve those other problems which are honestly everybody solves stuff in a different way anyway like scroll behavior is a very very hard thing to generalize across all websites the same thing with like transitions and animations and stuff it's very very hard to say everybody's going to do it like this so it might be better left in user land anyway alright thank you very much I'll be around if you have any questions you
Info
Channel: React NYC
Views: 10,176
Rating: 4.9341564 out of 5
Keywords: React NYC, React.js, React Training, jQuery, React declarative model, declarative programming, React Router
Id: vyO5wKHlWZg
Channel Id: undefined
Length: 47min 4sec (2824 seconds)
Published: Sun Nov 19 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.