90% Cleaner React With Hooks - Ryan Florence - React Conf 2018

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Applause] so my talk is 90% cleaner with react hooks I used you might know me from react router I used to work at react training but now I'm running a reach Tech where I'm trying to make react accessible for the developers and their users so I've got open source their workshops online courses and stuff take a look and then also give me a follow on on Twitter dan just said don't rewrite your apps in hooks I think you should we're just gonna we're just going to dig in we're gonna do a bunch of code here and see how hooks feel in a little bit more real-world use case so this is this is kind of this is the state of react today right we got these render props and they get all nested I've loved these things since I saw them at react Europe when Cheng Liu showed us react motion but I have not loved the syntax disaster is what I've started calling this render props big trade-off is that syntax disaster dan and Sophie covered really well a lot of the problems that hooks solve with this so I won't go into any more detail except one other thing is something that's always bothered me about these render props is it gives a false hierarchy here I've got two media listeners where I'm listening to the media query and so I can see if this thing matches that those two queries and it looks like there's a hierarchy here but there's actually not so let's let's see how this code feels when we switch it over to hooks here's how it's all implemented we've got some initial state here we set up when the component mounts we do a quick check here because between initialization or a construction and mounting our screen size could have changed especially with suspense coming so we set some state just in case it changed create a listener add the listener and then we add removed listener to our component instance then we've got a component did update we do a little dip here because if our query changes we want to reset up this listener we subscribe to it and we need to clean it up as well and then when we unmount we clean it all up and of course we yield out that state or call back with that state with the render prop so let's come to the app and and switch this up instead let's say yeah I'm gonna use let there haven't been enough like semicolon conversations lately so I figured we can start some more of those kinds of conversations and my screen size is kind of small and I'm getting old and typing five characters is you know I'm pushing I'm getting close to 40 I'd rather just type three characters but anyway we're going to use media here let's grab this out drop it in there and then we're gonna have a large same thing use media grab this put it up here I got some extra quotes now and then we just get to delete stuff yeah so many little Woo's out there everyone is pumped about this let's go let's go implement it so let's make use media work so we're going to say function use media and we get the query in as an argument and then up top we're gonna have our we're gonna have our state so we're just gonna slide all this code around and see where it moves so our state comes in like this and then we will say let matches equal use state and we put in that initial state there and of course we need that second part of the return of set matches so that's why state goes component did mount we just call set up so there's really nothing to do there but we will use an effect here you can think of use effect as component did mount and a few other things but for now just component did now so when we mount we grab all of this stuff and rent it so we're going to move all of that into the effect and in here we're no longer reading this stock props like query send miss that one as well we're actually just reading an argument that comes into a function it's funny because we've said that about react for a long time right think of props like arguments to a function well that looked it is an argument to a function we're not gonna read from this state that matches we're just gonna read from matches because we already got it right up here and then we're not gonna call set state we're going to call actually let's reuse as much code as possible set matches it's important to be efficient no matter what task you're doing don't want to waste CPU cycles up here and we've got our listener we don't call set state let's try that again set matches I practice last night doing that and then we add the listener and this this not just this but this this is kind of difficult as we've seen you all know that so I don't need to spend any time talking about that so with the hook instead of having to track this this function across our instance we just get to hand that over to react so you know what I don't care when that's supposed to be cleaned up you figure that out okay so now I've got our component did mount in their component did update so this is interesting when we update we dip the prop and see if we should remove the listener and then setup again do we get like previous where do I do it there's a second argument here the second argument we tell react what stuff matters about this hook so I just tell it well that's almost it I say hey the query matters here some of you were looking at this thinking I liked hooks until now this is the moment no wonder Dan didn't want to cover that part well let Ryan do it he bombed reactor alley so he can alright so this is a whole lot like component did update as well so react is gonna do that diff for us so before you get too grumpy about this API you know and you're probably thinking like oh I don't they passed the arguments back into us don't think of it that way don't think of it as these are arguments that I used in here think about a div and if you put will do the innerhtml maybe we did we put the inner or the query as the HTML of the div we don't think about this but react is diffing that query I mean not really it dips the react elements and it does the reconciliation but conceptually we can think react looks at that Korean goes oh that's different now I'm going to go do some Dom node or a Dom node I guess it's the the Twitter age and we could change the inner HTML to something new right it's gonna go do an effect based on when that query changes so don't don't get too grumpy about this thing we're just we're just letting react do it now I mean we had to dip it anyway and I can't tell you how many bugs there are in my workshops where people forget to dip the prop and component did update and then set things up again so react is now going to handle this diff for us and it will actually remove the listener for us and then it will also set everything back up goodbye component did update all right component will unmount well yeah also if the query changes will unsubscribe and if the component unmount it'll do that so all that's left is our return and then we return matches let's save it double check our work looks like it works [Applause] 90% cleaner let's see I mean even like I've got prettier set to like 52 columns or something like that and it just it's just kind of like you look at this thing like a hikes close your eyes if this makes you dizzy and now it's all just I'm in so cleaned up I don't really like talking about clean code I like code that works I don't usually care how clean it is but I love it when you get an abstraction that actually helps you write code that you don't sort of feel bad about when you deploy it I'm gonna I'm gonna put this back to the to the old way so we'll look at it again later let's look at a little bit more real-world example and what better way to talk about the real world than to look at pictures of the galaxy actually it's not our galaxy these are these are pictures from the Hubble Space Telescope we're gonna build a carousel so I went and did some research on how to build an accessible carousel for people using the mouse screen readers keyboard navigation and all that kind of stuff so we're gonna we're gonna do full-blown carousel here we're not going to do any half stuff or show Mary Poppins window width that's a little creepy if you're tracking that Dan okay so here is here's our app let me bump up the font a bit I've got a current index if I switch this index you'll notice that the slide changes back there we've got some the slide nav is right there here are the slide controls this bar down here is actually a progress bar we're gonna animate this thing so that we know when the next slide is coming and then when we click these we're also going to manage focus so we're going to move focus from the button that we just clicked to the actual slide so that someone using a screen reader will be able to read the text inside the slide they don't want to just change something and then not read it so let's let's bring this thing to life so we're going to use state here and then we're gonna have our set current index so this is a lot like object D structuring it's kind of new for some people a radies structuring is in its in other language that's in Ruby that's where I first learned these structuring but yeah it's just like object destruction but it's arrays and it's actually been around longer than object D structuring and job is good so let's what should we do let's do the list of the forward and back buttons first so I'm going to come down here to our controls play/pause gonna have a space or gif to have a good app I told you I was old half of you don't know what that is but those that do okay what we want to do want to say set current index we're going to go backwards so we need to do we're going to do current index minus 1 but we want to cycle through if we get to the first one we're going to do a little bit of computer science here got from stackoverflow don't trust this code you sometimes like you look at Kodiak that's kind of weird how they did this but I mean Ryan wrote it so I bet he knows what he's doing with it nope so I encourage more comments like that and then down here what do we do we say on click we're gonna set current index here as well but this one's a little bit easier so we're gonna do current index plus 1 and then modulus slice that length so again this is just so that it'll cycle through let's save it come over here cool what should we do next these slideshows usually automatically play right so we're not going to be what I want to do we want to have like an interval or a set timeout or something right but we're going to use effect if you want to put a clock on this page then that's an effect that's something we would have done in component did metal so instead we do it and use effect here and we will set timeout I've got a slide duration already out there and once again we're going to set current index to current index plus 1 I love computer science so much ok let's save it it's about 3 seconds all right pretty cool play pause let's get the let's get the play button working we're gonna need some more state so I'll say is playing I mean that could work is play nine and set is playing we'll use some state we're not playing yet let's come down to our controls here's play and pause so I'll say is playing so if we're playing then let's render the pause button so when we pause we set is playing and then when we play we set is playing to true wait a second I said false if is playing then set timeout it's important like Dan was talking about you don't do this outside those effects need to be there all the time the way to think about that is you actually really really love hooks in fact you love them unconditionally but just that just came to me during band's talk and I'm really glad that landed hmm I was actually Jarrod Palmer told me to get a Captain Hook outfit and like come up here I'd be like I'm gonna show you how to program with hooks and for 30 minutes try to type on my keyboard and we almost went to the strip to go get one but that one might have not been safe for work so we didn't okay so I am I'm gonna save this so it's not playing one two three okay now I'm gonna click the play button one two three cool I'm gonna click the pause button I don't know if I when did I click that so I'm going to play again okay now I'm gonna pause I should stop play is is dance still in here I mean I've only been using these for like ten minutes so clear my time out return what all right here we go sorry that was staged I want to see if Dan would actually come up and I know everyone on the react team is like when is he gonna pass the second argument to use effect okay so this this is working right now but it's it's got all sorts of problems this is my favorite one so it's playing and then I click click click click click click then I'll stop I'll get one more and now it's done so we've got to let react know it's got to do that component did update diff and it's got to we need to clear this time out because when I'm when I'm playing and then I hit pause there's that last timeout that's still there that hasn't been cleaned up so that's why we get that one extra in there so what we need to do is first tell react that oh sorry and then the other bug where the click click click happens is I click next next next and the timeout doesn't get cleared and I end up setting multiple timeouts because the current index changes and so I get a re-render on every single one so I get a set timeout on every single one of those so I'll come in here and I'll tell it if the current index changes or if is playing changes then I want you to clean up my mess so we'll let our timeout equal that and then we can clear timeout right there so now as that state changes over time react knows when when to clean stuff up so we got one transition I pause it and then it should be done and again don't get grumpy this arguments fine it's just like just like this is playing react is already doing dips for you it's already doing that in the reconciler but we're not rendering elements here so this stuff can't participate in that kind of a diff and so when we drop this stuff in here we're saying okay plug this affecting to directly reconciler based on these things just like our just like our elements the owners I emphasize that as I was so grumpy about these okay what's next this progress part let's do the progress bar this thing is really fun so down here we've got a progress bar and we're gonna animate if we're playing so let's go up to the progress bar let's see how it works so we've just got this value here and watch it's gonna bump up to 75% now we can put it back down to 50% and then we could also just use progress and yeah I mean you know you're not sure if you want to clap could you have no idea how it works I think I like it this is not built-in to react this is this is my own custom hook that's so cool though it's like I had just a singular value or a static value and to refactor to something stateful is just a function call like it's it's still kind of blowing my mind I haven't gotten bored with react I've been teaching it at workshops for three and a half years thousands of people maybe a hundred workshops and I still don't get bored with it and now there's this stuff and I'm like a little bit hyper when I talk about it and I'll tell you what the last workshops or the last couple of weeks have been impossible to keep my mouth shut there are a couple people here who are at some of them and yeah it was I'm like yeah I know a render props are kind of weird I heard of components are kind of weird but just wait two weeks I got a survey result back that was like I want my money back everything's changing in two weeks and I was like okay like maybe I should not tell them anything at all it's actually not that great look didn't reset okay so how do we get these these effects to reset we just talked about it's that second argument right so that react can diff and change it so our progress bar down here only knows about time and animate and then our use progress let's go look at it don't worry too much what's going on here there's just some requestanimationframe and calculating time stamps but it it will reset if anime and time change I don't want to have to tell my progress bar all about current index and is playing if I could pass that stuff in then it could pass that stuff to use progress then it could pass that to the argument there but react already has a built-in way with our elements to reset state whether you're using hooks or you're using a class component it's the key so you need to say if the current index or is playing changes I want a different instance of a progress bar and then the state inside of the hook I mean it doesn't get reset the thing just goes away and then you get a brand new one but you can think about it as this will reset the state of the progress bar whenever those two pieces of state change cool and now I want to read about the Eagle Nebula hey I want to read the Eagle Nebula pillars are bathed in put right they ultraviolet light from a grouping of young oh my drives me crazy on websites when like they actually have a carousel that you actually care about and then it just keeps on going so how can we fix that when we click next or previous we could say set is playing false right and then we could do the same thing up here on here set is playing false but the more state we get in these components you kind of end up with with this and that's that's fine but maybe you'd rather do something a little bit more conventional where maybe you've got some state to talk about and maybe you would like to co-locate all of the management of that state with something like I don't know dispatch and to do that maybe you would like to use a reducer this is actually built in to react hooks so it comes comes straight from react we pass it some initial state so the curring index is zero we pass it is playing faults and then in here I'm just gonna I'm just gonna write the reducer as quick as I can I'm really bad at switch statements though I didn't use them until Redux came around I'm still not sure how I feel about switch statements but uh I can finally write them without having to stackoverflow it so we've got case progress and we've got case next and these these basically do the same thing so I'm going to return all my state and then I'll say is playing if I'm progressing from slide to slide I want to keep playing and so I'll say is playing is action type if I could tie it it's progress so it'll keep on playing but if I click Next it won't be playing anymore and then I'll do the current index yes our computer science almost forgot what to do at the end there and then okay so that's what are we yelling about when a default case alright do you fault return our state I so got next and progress let's copy this and do previous and oops we're going to subtract from their slides dot length and then is playing is false and then what else we got we've got case play so when we play I want to say is playing true and then we've got pause and it's playing false one two three four five all right so that is all of them I'm gonna delete this stuff and then we're gonna have some some disasters right here so let's let's fix all of these bugs and what else we got if is playing so it's state is playing almost so we're not gonna set current index here we're going to dispatch progress and then down here more putting state on there what else you got yes lint what else you got stay current index we're getting close we don't set his playing we dispatch a tight play and then down here same thing oops this one should be paused I heard somebody grumble over here thank you whenever you hear the grumble it's like you did something wrong but you don't know what they said let's just just get nervous so previous slide won't do all that anymore we just dispatch type is a previous same thing here we don't have to do that those two things we just got to say what we're doing go to next a couple more bits here not Sophie bits these are Ryan bits and then I got one fan and then this oh we already covered this that's a for the screen reader to know that something's happening okay happy try not to make you dizzy sliding up here I think it's I think it's happy let's save that [Music] [Applause] throw this stuff on context you can feel in the rest of that statement sorry mark I wrote a blog post called the suspense is killing redux I might write another one called Redux gets the hook but no I I love I love reducers from Redux I love thinking about my state on one thing I don't think we talked enough about colocation in the community and we're seeing it now dan talked a whole lot about it where we used to have this kind of stuff spread all over the place in a component but we kind of thought like oh but it's all in a component so its co-located but we didn't realize that if we looked a little bit closer we had logic spread across our component and that stuff wasn't co-located so hooks led us co-locate these effects colo-colo key our state and use reducer looks us co-locate the changes to the state in this component we're almost done let's uh let's get these things to work and manage some focus so I'm gonna come down to those actually that's what we have a reducer we can actually think about our app and a little bit higher level so we could say what we call this one I'll call it go to cuz I'm old enough to know that that's a thing but young enough to not know what it really was will have a current index and that will be on action dot index and so then we'll come down to our slide nav here it is and we'll say on click let's dispatch type go to index and use my keyboard now notice the down down here how it's it's highlighted so I'm using my keyboard to navigate around and so what we actually want to do here for a screen reader is and a keyboard user maybe this slide has a form in it or something we actually want to move the focus up to that element and so we'll know that we did it right if this isn't doesn't have that extra circle around it now I got a say here I've been using hooks a little bit longer than the duration of this talk but not much so I'm not sure what the right way to model this focus management is what hooks yet and so don't don't think like oh wow this is cool that's I'm gonna do it in my apps I think I think we'll eventually figure out a better way to do it but for now this is this is just kind of the first thing that's come to my mind so I'm gonna have some extra state here and call it take focus and then in each one of these actions I'm going to say take focus faults and then all of them except for go-to and this one I'm going to say true so I want to take focus when we're going to something specifically and then down here words are sliding that our eye slides so our slide we can pass in state take focus and now let's go up to our slide sorry a little bit of bouncing around so here's the slide it gets that prop it also knows if it's the current slide we throw tabindex on there so that we can actually focus it and to focus an element we need our Ref hmm so with everything we've seen this morning where do you think we can get a ref from if we need to use a ref how might we use a ref yeah and then if we need to focus we use effect and we want to change the focus depending on if we're current and if we should take focus and I'll say if we're current and we should take focus ref current focus notice the circle moves offer there there we go [Applause] ninety percent cleaner react thank you very much [Applause]
Info
Channel: React Conf
Views: 68,810
Rating: 4.9450469 out of 5
Keywords:
Id: wXLf18DsV-I
Channel Id: undefined
Length: 33min 36sec (2016 seconds)
Published: Sat Oct 27 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.