Placeholder Image

Subtitles section Play video

  • and I'm here to talk about hooks.

  • What's really great is inconvenient is that half the room already knows hooks and use this react so I don't have to introduce it very much.

  • My name is Shawn.

  • I go buy sweets on Twitter.

  • Um, I work at nullifies the developer experience engineer.

  • I moonlight as a moderator on the reacts Subreddit.

  • There's 100 20,000 of us talking about react and getting jobs and getting started in react.

  • If you wantto join and hire people, uh, please join us.

  • And my other big thing is that I learned in public so anything that I learned, I tried to do talks and block posts and share stuff, and this is one of those.

  • So I'm gonna start.

  • Just talk about talking about red name or greet.

  • He's one of these painters.

  • You might recognize the painting in the background.

  • That's one of his more famous ones.

  • That's the man in a bowler hat, and he does several variations of this.

  • This one's probably you've seen this a swell and they're all surrealist like they look.

  • They look really good year skills, but he just paint something that's not exactly riel and it's meant to make you a slightly disturbed, slightly like out of out of kilter.

  • Um, this one's also I really like this because it's like, just like a floating rock.

  • That's probably the inspiration for Pandora.

  • And, ah, this one I also like.

  • It's just kind of like there's, like, human intimacy, but they're not really seeing each other.

  • You can't see them.

  • Um, he has a thing against painting faces this one's about, I think, in the impermanence of life like things remain and the man just goes away.

  • Anyway, the most famous one eyes Probably this one.

  • Um, I'm not good at French, so but it just says This is not a pipe.

  • It's a picture of a pipe is not a pipe.

  • It's an interesting, useful model for people to discuss.

  • It's meant to make you slightly off kilter, but well, I think I think it's actually useful, right?

  • Like you can complain to this and everyone knows what you're talking about.

  • It's a pipe, Um, and this is the frame that I wantto set this talk with.

  • Like, this is not a pipe, but it is a useful discussion off a pipe.

  • Um, how does that have to do?

  • And I'm updated it for the millennials s O.

  • This is a little bit more updated in terms of I mean that mean was like, Ah, 100 years old.

  • This is a bit more reason.

  • And this is the more recent one.

  • Is this the place?

  • I always I'm very good with me.

  • And, um so So how does one have to do it reactivates?

  • I'm gonna assume that I've ever seen the talks and see the sea, the video and see the docks.

  • Obviously, go check it out if you have it.

  • And mainly hooks were immense.

  • Have replaced on the problems with classes, in particular by Link that this That's not the only issue.

  • And that's not the primary issue.

  • But that is one of the issues.

  • But but way happen never has changed the problem with that, with closures that there you sort of run into stale closures all the time and having toe refresh your memory on what closures are.

  • So I was I was running to that as well as always adopting hooks.

  • Um and so I looked for a start.

  • Loafer definitions.

  • Obviously you turned the m d.

  • n a closure is a combination of a function in Mexico.

  • Environment with the function was declared very clear.

  • Right on blah, blah, blah.

  • Like I look at all these, uh, comments.

  • And honestly, the most clear one was actually w three schools.

  • It's that closure makes it possible for function toe have private variables.

  • That's the only time I've ever found w three schools useful.

  • Um, but thank you anyway.

  • So So then I had this exercise of, like, why not?

  • Right?

  • Hooks and scratch and practice closures as well?

  • Because if you can have private variables, I kind of state full functions.

  • So this is the part where we start life coating and we have time.

  • Okay.

  • So, um, what I mean by state full functions, Let's just have a variable in the global scope.

  • I hope this is big enough for everyone very born in global scope.

  • And I'm gonna come.

  • I only have a function called ad.

  • Um, if I can spell under intense scrutiny and pleasure and pressure um, food plus one, it's gonna return fu.

  • And now every time I call it, it's gonna increment by one.

  • Right?

  • It's a state full function in the sense that as every time I call it, there's some internal state going on that's, Ah, that's that's being mutated and you can see the result of that.

  • The problem with this is is that the full variable is on the global scope.

  • So any intermediate script can just mess of it all right.

  • Like I could just say like, full 99.

  • And that screws up my my expectations of what's supposed to happen If I make it, I'm writing a library.

  • That's not a good um, that's not very secure.

  • So I need to contain on each of protectors variable somehow and move it off the global scope.

  • And how do I do that?

  • I move that inside the scope of the of the function right?

  • And so now jobless have just refuses to run.

  • It just doesn't let you modify food.

  • That's great, but I give up the state for ms I gave.

  • I just call it every single time, and it just has the same has the same value.

  • So how do we How do we fix this?

  • I can't exactly fix this with his FBI, but I can do is returning function inside of the function.

  • Um, and duty.

  • Exactly.

  • The thing inside there.

  • I'm just switch this to get ad, uh, function.

  • Higher order function, I guess, um, and I'm gonna call, get added there.

  • And now it's still works again.

  • I have a state.

  • I have my state full function back, and I cannot touch food inside internally.

  • Right?

  • So those are the requirements that we want.

  • We want state for functions, and we want them to be protected.

  • We want that state to be protected the last week.

  • JavaScript refresher.

  • So this is a closer right?

  • I ad the ad function.

  • Is this anonymous mentioned in here?

  • And it closes over this fool variable that's inside out to get at a function.

  • No one else can access it, but and I can access that every time is executed.

  • That's closure.

  • So the last thing I'm going to remind you and then we'll actually start to clone react is that if I don't want this ugly get ad thing, it's kind of ugly.

  • I can just delete this replace, get ad with a parenthesis, and I'll just paste it in there, and it does exactly the same thing.

  • So this is the module pattern is also called the fee The immediately invoking function expression a lot of your scene if you look at bundler output.

  • All right, school react.

  • So first thing, when a clone is the U.

  • S state variable you state hook, it takes an initial value, and, uh, in its vow, I'm gonna call it.

  • And what is their return that returns a state?

  • And it said state, I want to refer a lot by the way, to the docks.

  • Like if people are new people, New tow hooks.

  • Definitely Check out the docks first before watching this talk.

  • Um, So how do you How do you define state and set state?

  • How do you implement that?

  • We're just gonna have some internal variable that's just called the internal value.

  • And we're just going to initialize it to win.

  • It fell.

  • Um, we're gonna have state, and it's just a sign it to Val.

  • For now.

  • This is wrong, but just get something showing on the screen and they will modify from there.

  • SETC takes a new value on DDE.

  • Uh, it sets that new value to the internal, Val.

  • Okay, good.

  • So now we have hooks in node Let's use it.

  • Count.

  • Set counts.

  • Ah, so this is de structuring a raid e structuring in on all that.

  • So again, these are all standard JavaScript patterns that, uh, pretty handy when doing this.

  • And then now we're gonna consulate out log count.

  • We're gonna set counts to two, and then we're gonna consulate count again.

  • So what I expect is to log out one and two.

  • Unfortunately, I log about one and one over here, and that means that I'm not really It's not really working.

  • Unfortunately, it actually is.

  • That second is working.

  • It's modifying internal value.

  • But the problem is, when I d structure this counts is assigned the value of one, and it is one here, and it is one here.

  • That's why we're logging out one.

  • So we need some place to just re pull the internal state again.

  • Um, one easy.

  • It's very cheap.

  • Way to do it is to turn this state into a getter function.

  • And now I can just call, get I just called the function and now in my state, full function back again.

  • So one into and, um, this is kind of hooks and note if you need hooks.

  • And no, that's that's all the implementation.

  • It's eight lines.

  • Um, but we want to do more than that.

  • The in reacts, you don't call it, get her function.

  • You just used the variable.

  • And it's live every time.

  • And it's just fresh.

  • And it's the correct value.

  • You don't You don't call it a weird get her function.

  • So we want a model that but involves a pretty large reef actor.

  • I'm gonna walk you through it.

  • You already know everything they need to know.

  • So I'm gonna zoom in a little bit.

  • All right?

  • So the first thing we want to do is put our hook inside of a reactor module, undercut this.

  • I'm gonna introduce a reactive audio.

  • It's gonna be a function that I immediately invoke, right?

  • I'm gonna pace my hook in there, and I'm gonna return the object.

  • Um, that has a use state property.

  • So now the only thing I've changed is in my usage.

  • I can call, react out you state, and it does exactly the same thing.

  • Everyone with me.

  • Right.

  • Okay, so So I've done.

  • I put a creative reactor module.

  • I have sort of wrapped up my functionality I can do that to my hookahs.

  • Well, what wraps around the hook?

  • A component, Right, So I can declare a component.

  • Um, and and that's is just a regular function And put the hook in there.

  • Um, normally have your rendering to the dom, but in this case, I don't have a dime.

  • I just have the console.

  • So I'm just gonna return an object and simulate that we'll get to the other stuff in a second.

  • So render, um, I'm gonna have consul dot log counts and then click.

  • This is just for stimulating.

  • I don't have a button.

  • So we're just gonna roll with this is the best you got.

  • Um, uh, and I'm just gonna put in a new object.

  • Forget the object.

  • Okay, So?

  • So the last thing that we need to do is we need to teach.

  • We have react, and we have the component we need.

  • We need We need to teach, react how to render the component.

  • So that's right.

  • The render function.

  • It takes a component.

  • Um, and a component is just a function.

  • Right.

  • So let's just call it, um and then the When you call it, you get an object that has a render in a click, right?

  • So this is called the Render right.

  • It's actually just put long something on the screen, and then we'll just return it so that we can do other stuff with the component on gonna expose that inside of my reactor module over here.

  • So we're at 16 lines, not too bad.

  • And now I can replace all this logging stuff and do something like react that render components.

  • We should see something show up on the screen up.

  • That's not exactly what I want, but whatever, um, and I can because there's a there's a return value over here.

  • I can take this and I can start accessing stuff on the object, right?

  • Like like the click function that wrote.

  • So I can just say Click on and I can re render it again.

  • Um, react.

  • A clique is not a function.

  • It zapped.

  • Okay, it's a little bit like t d d get instant feedback in this rebel thing.

  • It's really nice.

  • Um, okay, So the only thing that's wrong with this now is I'm logging the state, get her right.

  • That's the That's the thing that we did just now.

  • It was like a hacky thing.

  • Let's just get rid of that.

  • Let's lift the value up to the internal value up to the scope of react.

  • Um, and we're going to get rid of the getter function.

  • We don't need it anymore.

  • And we're just gonna let that get her function in clothes over the internal value that the you state cook close over the internal value.

  • So now it just returns every single time.

  • Um, it it renders.

  • So So this is the, um Okay, So this is, uh, love a new value value.

  • Okay, um, I'm running into something that I didn't expect over here, So I'm gonna try toe debunk a little bit, I think.

  • Um, okay.

  • Sitcom.

  • Yeah, I think I think I said count.

  • Oh, uh, yeah, I need a plus one.

  • Of course, if I'm sending comes to the original accounts, it's not gonna increments, so Yeah.

  • Okay.

  • Um, so I practiced this a lot.

  • So it's very unusual for me, this girl like that so you can see we have our staple functions back.

  • Right?

  • But we've gone through a whole bunch of ceremony, but now we have a reactor module we have a component, right?

  • It kind of looks like a component.

  • Andi, we can We can do things to the component and updates and state.

  • So that's really good.

  • Until you try to have multiple states, multiple hooks.

  • So let's just have a textbook.

  • It's gonna look slightly different so that you can differentiate between the number and the text.

  • I'm gonna call it Apple.

  • Just because that's the first thing I think about, um I'm gonna log it out as well.

  • So we're gonna get out and surrender, and I'm gonna have a new method.

  • I'm just going to call it type.

  • Um, I'm just gonna take a word, and it's gonna set text to that word.

  • Okay, um, get rid of this and we will use that type.

  • Um, function here and you'll see what's wrong with it in a second.

  • Uh, so I'm gonna sit that two pair.

  • Okay, so So what's happening here?

  • Our component is here.

  • It's got two hooks.

  • Um, the first click happens and both counts in techs.

  • They're both set to two, and then we have a thought.

  • Type on both counting text that both had two pair.

  • So what's wrong?

  • with this This image We're trying to use two hooks, but they're they're they're just They're just using the same store in the memory, right, Because we only have one variable, and it's constantly overriding that single variable.

  • So the mental image of hooks that you have now should grow a little bit.

  • And you should think of hooks as a raise of effects.

  • So that's just using array and well, and to know which hook we're currently operating on.

  • We also need an index, so I'm gonna have an index of zero.

  • So now, now we're now it's pretty clear we're gonna replace all the internal values with just hooks in the current index.

  • So now nothing has changed because, um, we're still not incriminating the index.

  • So I'm gonna have a rule that at the end of the at the end of a hook after we're done, we should just always incrementally index so that the next what can take conflicting take place so that we haven't independently updating count in Texas not changing.

  • That's good.

  • But over here we still have this weird bug, and that's because I just keep incriminating index plus one plus one plus one.

  • That's what I need to reset it back to zero.

  • So that every single time, a rear ender, um, it's going to start and go through all these hooks from scratch because it's referring to the internal hook storage.

  • So, yeah, let's just set it to zero.

  • And now I'm gonna break everything on.

  • This is because of a very subtle bug.

  • Again, set state is called a synchronicity Is that state is called after render right on.

  • By that time, hope the indexes actually set back to zero s.

  • Oh, this this index being alive value.

  • That's a problem for us.

  • The way to fix that problem is to freeze it.

  • So let's have an internal index, and we're just freeze it.

  • And will that set state close over second uses your closure clothes over that internal frozen index value?

  • Okay, so now we have a component.

  • We're rendering it.

  • We have a count of one.

  • We're clicking.

  • The accounts are based on two.

  • The text doesn't change.

  • Then we type pair and then count doesn't change.

  • Tex changes.

  • So we have independently moving states right on.

  • That's something that's a new paradigm in the hooks model as well that every component used to have one object for state and everything.

  • You were just forced to put every all you stay on to that object.

  • Now, you have independently moving states, and you can be a bit more precise with that.

  • All right, so, um, and you can already start to see some of the issues with hook some of the rules of hooks.

  • So these are when the people introduce hooks, I think, uh, the biggest problems with folks that people had was that you?

  • You you have to call them unconditionally.

  • You couldn't put them in sending if or loop or some sort of dynamic values.

  • So I just want you to imagine what happens to this if I do like math at random, more than 5.5.

  • Right.

  • So this gets this gets called half of the time.

  • What is the hook index value of this?

  • This is this Should be one.

  • Okay, next value.

  • But sometimes it zero because this doesn't execute.

  • And so the state values get get off.

  • Right.

  • So you're just not allowed to do that?

  • And that's why we have winters.

  • And that's why you understand the rules of hooks just under fundamental basis.

  • OK, so, um, we're not done.

  • I'm not happy.

  • Um, we only have the state hook.

  • We also have the effect took the best way to model.

  • This is to just use it, and then we'll backfill What?

  • That what?

  • That is so ah, use effects hooked.

  • Takes a call back.

  • Um, we'll just say consul dot log Just calm.

  • Um, and then it also takes an optional dependency array.

  • I'm just gonna use an empty area for now.

  • All right, so So we have that a p I Let's just Let's go implement it.

  • Right.

  • So this is our module again.

  • Eso function Used effects callback.

  • Independencia ray.

  • Okay, so this is the hardest part of the talk.

  • Bear with me, but I know what I'm doing.

  • So good.

  • Um, let s o So we wanna have this variable we just have Like, like, whether it has changed or not.

  • Just said it's a true So by default, we're just going to keep re rendering.

  • And if if the dependencies have changed, we're gonna call the call back, right?

  • That makes sense.

  • If the dynasties have changed, we're gonna call the callback, So the hard part is to detect change over here.

  • Um, in order to check change, we need to basically, def, the old dependencies and the new dependencies.

  • That means we need to store and keep around the dependencies somewhere.

  • Um, where's a good place for that?

  • Turns out it's a hoax array.

  • So we're gonna story inside of the hooks away, and we'll draw it out at the start of our effect.

  • Um, the old dependency.

  • So hooks, Index.

  • Okay, sometimes this is undefined, though.

  • So that's why we need to guard it with an if, um, and by the way, always increment the index at the end of the okay, so sometimes it's undefined.

  • So what we're gonna do is replace this and just go.

  • If the whole dependencies do exist, that means you have an older Ray.

  • And in New York, this is the hardest part in the entire code.

  • So buried me.

  • So we're gonna modify.

  • Has changed to look at dependency.

  • Ray, we wanna have We want to look at some of them, want to do a raid out some.

  • That's a lesser known array prototype method.

  • We want to look at the dependency and that index and we want to compare that dependency to that index.

  • We're gonna use object.

  • That is.

  • So, um, a lot of people I don't condone its reactor uses.

  • Object is internally because not a number Triple Eagle is not a number is false.

  • Object.

  • That is not a number and not a number.

  • It's true.

  • So that's just a slightly better option.

  • So people went with that.

  • So we're gonna gonna say object?

  • That is dependency and the old dependencies, the correspondent index off that old dependency.

  • Um, I think that's it.

  • Oh, and then we need to expose it in our reactor module.

  • Bye.

  • Boom.

  • Um, so what do you have now?

  • We have a component.

  • We have a use effect of an empty array.

  • It start only runs once at the start and never again in any of the updates.

  • If I put in counts here, then it depends on that.

  • Counts and updates.

  • When the count changes from 1 to 2, it runs.

  • If I change it to text from when the text updates from Apple's a pair, it runs.

  • And when I delete it, it also overruns every single time.

  • So that's the speck of use effects, and it wasn't that hard right to implement all this.

  • Um, so this is normally where this is as far as I plan to go.

  • I was like, Okay, you've kind of proved out the hooks model.

  • Um, but I'm very ambitious person, and I was like, this kind of looks like react, but it's not really react.

  • Everyone kind of knows that.

  • So what can I do to put this on the dome?

  • Which is a really stupid question to ask for a live coding talk, but we're gonna do it.

  • We're gonna This looks like node, but actually, we have not been quoting in note at always.

  • Just been the consul on.

  • And I have have a browser implementation here, thanks to coat sandbox.

  • So let's do it.

  • Um, actually, that was probably a bad idea.

  • I have some have some pre prepared CSS.

  • I'm gonna import that.

  • It's not showing the auto fill any media background.

  • Very nice CSS effect for demos.

  • Um, and then I also have some utilities that I imported.

  • So, um, I have a create element.

  • Objects that I have from my you tells father, um, and create what create element.

  • Does is what JSX compiles to buy babble, right?

  • Hopefully everyone knows that I'm gonna expose it inside of my, um, inside of my reactor module.

  • And now I can use JSX inside of, uh, my component.

  • So I'm gonna say, Dave, Hello, world.

  • Let's get something to show up on the screen.

  • Um, unfortunately, we're not done.

  • Uh, sorry.

  • Let me just comment that out.

  • Unfortunately, we're not done.

  • We also need a render function that actually rent take renders to a dom element.

  • So that's just import render.

  • Okay, um, the render a p I that I have written is slightly different because it memorizes the hooks.

  • So I'm just gonna delete the render function that we wrote, and I'm gonna expose the render function.

  • It's a high order function.

  • It just takes the hooks.

  • And it has, um, and also it's a render function that we can actually use.

  • Like you wouldn't use a normal render function.

  • So let's just go like that.

  • Um, a very nice, um, So we have jazz X.

  • This is Jess X, and it only works because of reactor.

  • Create element in the babble babble J six, plug in.

  • Okay, that's keeping s o.

  • So what do we do?

  • Let's actually prove out that everything works.

  • And this is a full reacts clone.

  • It's not.

  • But trust me.

  • Um, so let's have a button.

  • Um, I took the opportunity to All right, you'll see what happens.

  • I'm gonna write a standard event Handler is gonna set counts.

  • Too complex one.

  • That was the first time I ever forgot the plus one.

  • And obviously, it's on stage.

  • Very stressful.

  • And it just says, click me, for example, and then it's gonna have the current count.

  • Yeah.

  • Everyone should be very familiar with this.

  • I don't have hot reloading.

  • Figure it out.

  • So you're gonna see me manually refresh a few times, so yeah, Button showed up.

  • I have Nice.

  • It's a nice CSS because I cheated, but, uh, if I click it, it doesn't work.

  • Why?

  • Because when remember when we were doing this, we were manually re rendering every time, right?

  • Their reactions.

  • This concept of a work loop, it always loops around to check if there's work to be done.

  • So we need to simulate this work, Lou, by manually doing it, um and I was like, Screw it.

  • I can write a work, Luke.

  • That's not too hard, right?

  • It's only, you know, we've got, like, 10 minutes.

  • Um, so that's right, a working, Um, And the work loop is simply I'm gonna set the index to zero, because every time you render, you have to set the index to zero.

  • We're gonna call the render function again, fasten their hooks argument on, and then we're gonna call the set time out with the work.

  • Lou, I want to set a loop of 300 milliseconds.

  • In reality, it's It's Chris.

  • I will call back.

  • So is much faster.

  • But, um, this is what you get.

  • Uh, this is what works for this demo.

  • So we have clicking.

  • We just live coated This, um, the last point I want to make I think in this entire thing is I have custom hooks.

  • Notice that we did not write any any custom hooks code, right?

  • Nothing here was specific to custom hooks.

  • But if I pace this pre prepared custom hook, um, let's see where the customer I have.

  • Ah, use dogs.

  • Hook.

  • It has.

  • It has a state it hasn't which has an array.

  • It fetches an AP.

  • I, um, based on the count that feed in conscious 12345 And it gives back a number of pictures.

  • A number of your l's of dog images, and itjust returns that image so I can use this custom hook again.

  • I didn't I didn't I didn't do any.

  • I didn't do any custom book specific code.

  • Right?

  • Um, I can use dogs.

  • It once accounts.

  • So I pass in the account from there, and I can render that into Ah, math item box.

  • Standard stuff completely and not accessible, by the way.

  • But I'm the only one accessing this code anyway, so it works.

  • Fine.

  • You should have until tag.

  • So So let me, uh, again, I haven't figured out how it reloading so but this is a fully working app, so thank you.

  • Thank you.

  • Um, so then I'm like, Okay, so the punch line, what is the punch line?

  • This is the punch line.

  • I'm just gonna paste it in.

  • And I'm going to remind you of what we're talking about.

  • This is not react.

  • This is not react.

  • I have a fully dynamic app.

  • Yeah, I have the full AP.

  • I have JSX have custom hooks I have the render.

  • I've cloned everything that you usually use.

  • This is not react.

  • Why?

  • I called this in 40 lines of code.

  • If you magnify it, it fits in a tweet.

  • Um, if you're If you're wondering about the utilities folder, by the way, the you tools for there is only 120 lines on.

  • And it's mostly helper functions like create text element and all that that JSX needs.

  • So this is not react what is react.

  • So that's Ah, that's my That's where I'm gonna leave you.

  • I have homework for you.

  • I want you to go home and write react from scratch.

  • I want you to practice.

  • I want you to know, you know, practice closures.

  • I wanted to get good at understanding a mental model and understand what you use react for.

  • You don't use react for this.

  • A p I.

  • It has really good, right?

  • We can copy it.

  • View of you will copy it like spittle.

  • Copy.

  • And, um but what do you use react for?

  • What is what is the hundreds of thousands of lines of code?

  • What is that for?

  • Um, I have my answer.

  • I'm gonna treat all this out later.

  • But I want you to have that curiosity.

  • Don't just stop at the surface.

  • And that's my talk.

  • You can see the full source at six.

  • That io slash talks.

  • Thank you.

and I'm here to talk about hooks.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it