3 React Mistakes, 1 App Killer

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
let me tell you about three mistakes  that react developers make they range   from design mistakes to mistakes that  will take down your application and we   don't want to do that we'll learn about  why their mistakes and how to fix them   and we will learn about react internals  in the process let's get right into it mistake number one is invoking  component functions directly   so here we have an application that has  two components we've got an email field   component and we have an app component and  the email field is simply a control input   it just has some state to manage the email and  then the input field and then the application   component currently just has a dividend so let's  go and bring the email field into our application   now I'm going to use the jsx Syntax for  this because it's the easiest thing to do all right this looks pretty good we have our email  field up here type into it looks fine and if we go   over here to our reactive elbow tools components  tab which you definitely should have installed   we see that we have two components we have the  app component at the top that has no State then   maybe email field component down here that has  a hook that has our current state in it you can   even change that state and we can see that state  updating dynamically how freaking cool is that   you should definitely have this thing installed  so let's try and out think react let's look at   this and say wow you know this email field it's  a function we should just be able to call that   function isn't that what this jsx syntax is doing  well let's try that let's go and instead of using   jsx here let's instead create an expression get  email field and invoke it see what happens is it   blow up well no it actually doesn't blow up and it  seems to work the only indication that something   may be off is now we don't have the email field  component anymore we just have the app component   and we have something called an email field hook  which is kind of weird what we've essentially done   is we have merged app and email field into  one super component and we've turned email   field into our own custom hook and  invoked it right in the middle of our   return statement now one drawback right  away is when we change the state here   the app component re-renders right away so  we have lost the encapsulation of re-render   when we had the email field as its own component  before then changing the data in that email would   only update the email field component now we're  actually updating the app as well so that's right   away something that's not great but hey let's push  on let's see if there's we can do more with this   let's go and take email field and actually make  a bunch of them let's make four of them and now   we see the console ninja here which is this red  text is showing us a preview of Coming Attractions   said it rendered more hooks than during the  previous render which is absolutely true so   let's go back over here is it still working okay  so it looks like it's working and I can even type   stuff in there and it does work so that's one  of the problems of this particular mistake it   looks like it's working until it doesn't and  then it blows up and it's bad so let's make   it blow out let's go back into our code let's  get rid of these extra email fields and let's   imagine that our product manager is asking us to  put a switch above this email field it basically   toggles whether that email field is shown or not  so we'll go and add a bully in for that switch we'll call it send email and then  we'll add some UI for the check box this just has the input field which is control  which is a checkbox field and then send me emails   hit save I go back over here to Arc   it works no problem but it doesn't actually  hide or show this email field so let's go and   use a send email to toggle that so we'll  say if we have send email field true   then we show email field and we're going to start  at false which means if by default we're not so   let's go take a look and we have 70 emails let's  click on that and boom so what happened well now   we've taken down the app we have according  to react rendered more hooks than during the   previous render so how did that happen well if we  look back over here the first time we rendered app   we had this send email and send emails rendered  to false and that's the one hook would be the   U State hook came down here and because this is  false we didn't render email field so we had one   hook in app and then the second time around when  we clicked on send an email and turned it to true   we again re-rendered app and we came down  here and now we went to send email we said   great it's true so we're going to render  email field which brought in another hook   so we started with one and we went to two and  that violates the rule of hooks which you can   never have a different number of hooks based on  the render you can never have conditional hooks   so there you go the fix for this is pretty obvious  you just change email field to be jsx invoked and now everything works as expected and we can go  take a look over on our components and we can see   that now app has its own state which is currently  true because this is true false true false true   and then email field his its state which is  currently set to nothing but we can go and set   it so there you go perfect and everything is doing  what it should when email field updates its state   only it updates and when sending emails updates  then the entirety of app updates so everything's   cool but let's go back and take a look at the  code and see if we can understand this a little   bit better so what is the secret sauce here of  jsx why does this work and invoking email field   directly not work well so understand that you have  to understand how your react environment works   you do not send jsx to the browser you send  JavaScript to the browser so if you've got   JavaScript jsx or typescript plus jsx you have  to transpile that source code this source code   right here into JavaScript before you send it  to the browser and that's often done by systems   like Babel or typescript so I'm going to go and  take this email field tag and take it over to the   Babel Rebel so this is a test bed it's a website  you can just paste in your code and see what the   mammal transpiler is going to create given the  input source code and so the input source code is   just going to be email field here and what bammal  creates is react.createelement email field null   wow that's a handful so let's go and take that and  paste it in here and see if that actually works   so I replace email field here with this Secret  Sauce that was created let's see how that works   go back over to Arc and yeah this looks great  so this is exactly what we had before so what   is react.create element well react.crate element  is how you create components in react so you give   it the component function or component class  or the tag name you can also do things like   div here and that's fine and what it does  is it invokes in this case the email field   function gets back the resulting elements it  adds those to the vdom tree and it says that   that part of the vdom tree is controlled by  that component rendering function email field   so that when email field refreshes  then that part of the tree is updated   the second parameter here are the properties  we're not sending any properties in this case   but if we were to send properties you would go  and send a object here with all your properties   and then the third argument would be any  children of this component that could be   just a single element or an array of elements  or what have you now obviously the easiest fix   in this case is somebody not to do react create  element manually but to let jsx do that for us   and there you go so what have we learned well  we've learned not to invoke component functions   directly and we've learned a little bit about  the react internals and react.crate element   now our next mistake is more  of just a coding design issue mistake number two is nesting component  definitions we have two components here we've   got app we've got email field and let's say that  we don't want email field to be used by anything   other than app well what I've seen folks do is  go and take the definition of email field and   literally drop it inside of the definition of app  like this and it looks good right I mean kind of   neat containment so let's see if it actually works  and when you know it it does work and this seems   actually pretty nice why am I reigning on this  parade well a couple of big reasons first even at   this size this component is starting to get a bit  bloated and when you take this pattern out to 10   15 20 sub-components which I have definitely seen  that component size the just the physical code   size is huge and it starts to get hard to reason  about second it's impossible to unit test email   field because it's embedded in app like this so  you can't unit test these components in isolation   third it's a potential performance problem every  time we are re-rendering app we are giving a new   reference to email field we're redefining it or  passing that off to react and it's unclear how   react should respond when we keep changing the  reference to the component function continuously   and four you've got a potential leakage problem  between the host component and the sub components   for example this send email could be used within  email field and it's it's not clear if that's   the right thing to do certainly you're not using  the basic mechanism of react which is to do prop   drilling or context you're kind of doing this  implicit sharing of state which is not great   so I just don't think this is the right thing to  do and it's unnecessary really even when email   field was outside of app it was still not  science outside of this app module the only   thing exported from this app module is app so  email field is invisible to the outside world   unless it's exported so there's no reason to do  this now before we get on to our final mistake   can I ask you for a favor if you've been taught  this methodology of defining components within   other components please comment in the comments  section down below and tell me who taught it to   you or where you learned it because I really  want to have a chat with those folks and get   some information about why they're teaching it  what the rationale is and hopefully convince   them not to teach it because I think it's a really  bad idea now our third mistake is kind of a fusion   between the first two mistakes mistake number  three is so convoluted and unnecessary I couldn't   even come up with a good short name for it let's  just call it locally invoked component functions all right let's go take a look at our app here and  let's say that we just want to go and add in an H1   for my app right at the top easiest way to do that  is to just go and add in an H1 from my app right   at the top I don't know why people are doing this  but Okay so we've got my app up here and let's go   back to the code and what I've seen are people  doing this they'll go and create an expression   they'll go and create a component  function which renders my app and they'll try and see if that works it doesn't  work and in fact it gives you a console error   about how functions are not valid react children  because they're passing to react create element   the div and then the div has children in it  and one of those children is this function   and react is like function what so and to  get around this people are then going and   turning this into an expression and then  invoking it okay and the result is it works   but it's a fusion of the first two  mistakes in this video the first mistake of   invoking a component as a function it's just a  bad thing to do and then the second mistake of   defining a component locally in this case we're  not giving out a name but we are defining it   locally so it's kind of a fusion of the first  few mistakes and it has all of the downsides   of both of those so the easiest thing to do  here is just to go and make it the H1 my app don't over complicate stuff I don't know  where this pattern comes from might be   another language tough to say but please  don't do this okay well I hope you enjoyed   learning about these three mistakes and  you now understand why they're mistakes   and how to avoid them and you've learned  a bit about react internals in the process   if you have any questions or comments please  put that in the comment section down below if   you like the video hit that like button if you  really like the video hit the Subscribe button   and click on that Bell and be notified the  next time a new blue collar coder comes out
Info
Channel: Jack Herrington
Views: 95,001
Rating: undefined out of 5
Keywords: react js, react js mistakes, reactjs mistakes, react js error, react js mistake, react18 mistake, react18 mistakes, react18 error, react18, fixing react js mistake, next 13, nextjs 13, next.js 13, next js 13, nextjs react 18, mui nextjs, vite nextjs, next, nextjs, next js, next.js, nextjs react, nextjs api, nextjs npm, react 18, react router v6, vite, react, reactjs, react.js, react app, react use, typescript, react typescript, react hook, react state, mui react
Id: QuLfCUh-iwI
Channel Id: undefined
Length: 13min 59sec (839 seconds)
Published: Tue Jan 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.