3 React Mistakes, 1 App Killer

แชร์
ฝัง
  • เผยแพร่เมื่อ 2 ต.ค. 2024

ความคิดเห็น • 482

  • @BAM99
    @BAM99 ปีที่แล้ว +96

    I have definitely seen all 3 of these mistakes at my old job, no body seemed to know it's wrong when I told them they treated me like I was wrong so thank you for this video now I can share it with them.

  • @samuelgunter
    @samuelgunter ปีที่แล้ว +116

    so far this is by far your best video of the year

    • @aditirana7787
      @aditirana7787 ปีที่แล้ว

      I am amazed I know that concept but don't know in so much depth that this can completely kill my app. omg I read about the same in kent c Dodds's blogs but did not know that this error can be undebuggable In large apps

    • @12px
      @12px ปีที่แล้ว

      Honestly

  • @tririfandani1876
    @tririfandani1876 ปีที่แล้ว +28

    I can relate to mistake #1 and #2, but I never thought about #3.

  • @dev__adi
    @dev__adi ปีที่แล้ว +16

    another issue with nested components is that the inner component lose its state when outer component re-renders because each time it's a new reference so React treats it as a new component. So it unmounts old instance and mounts the new instance.

  • @farreldarian4215
    @farreldarian4215 ปีที่แล้ว +2

    I’d say for the mistake #2 where is placed inside App.tsx, not within but together with , is quite reasonable to encapsulate re-render.
    Probably much proper example would be instead of that is used somewhere under the component tree. Then inside there’s an effect that subscribes to input changes that’ll only re-render instead of the whole
    One might say that it’d be better to create another file, but sometimes it’s quicker to just write at the same file. It can be refactored later.

  • @usbgus
    @usbgus ปีที่แล้ว +1

    I did the first thing literally today. So thanks Jack and thanks TH-cam algorithm. Great timing.

  • @hardikganatra2453
    @hardikganatra2453 ปีที่แล้ว +15

    Your videos are pure gold Jack Herrington Sir , please keep going. If possible just write a book on React and Typescipt.
    You are the kind of teacher whole react community needs. simple and straight to point without jargons and over
    bombardment of information.
    Thank's onnce again !!! may god bless you

  • @luizpaulonascimento9162
    @luizpaulonascimento9162 ปีที่แล้ว +8

    This is an awesome video. I've worked in a codebase with a bunch of this "Component()" instead of "". I've always avoided to do it and thought it was a bit off, but never knew why, so I've never changed it nor talked to the person who wrote it. Now I have the technical base to do it. Thanks

  • @marianbuciu7853
    @marianbuciu7853 ปีที่แล้ว +1

    I need to see all of your videos!
    Didnt make any of these mistakes though, but you explain well.
    Can you also make some advanced videos?
    Can you explain how to make a config file ? (do you use useContext?, do you just make a file? ) How do you manage your code? What is a “correct “ directory pattern? etc..😊

    • @jherr
      @jherr  ปีที่แล้ว

      Have a look around, I think you'll find a lot of what you are looking for.

  • @juandsoto1651
    @juandsoto1651 ปีที่แล้ว +15

    There are some mistakes that we know should be avoided no matter what but we don't really know why. This kind of videos with your gorgeous explanation let us go deeper and understand those mistakes.
    You're the G.O.A.T Jack!

  • @boris_raduloff
    @boris_raduloff ปีที่แล้ว +2

    The third pattern usually comes from people who want to use more complicated logic in their component. For example, I might do something like this if I have a conditional view that I have five options from and I need to chose which view to render based on a state hook. I don’t want to write five nested ternary operators so I might do this weird function gimmick instead and have a switch statement or a bunch of ifs inside if its more complicated. Now that I’ve learned why this is bad, I’m open to suggestions on how to handle such cases besides the obvious “just refactor”.

    • @DaumChannelGamePart
      @DaumChannelGamePart ปีที่แล้ว

      me too, i deal with many error codes in error boundary, do #3.

    • @javierfuentesmora1814
      @javierfuentesmora1814 ปีที่แล้ว

      Let me know if you find something because I face the same issue …

    • @dealloc
      @dealloc ปีที่แล้ว

      Use objects to map values to components instead.
      Define an object that has the different variants (as const is used for TypeScript to get better type-safety):
      const componentVariant = {
      variantA: VariantAComponent,
      variantB: VariantBComponent,
      ...
      } as const;
      Then reference it within your component like `const VariantComponent = componentVariant[someVariant] ?? FallbackComponent`. The fallback component is optional. If you don't want to render anything if nothing matches, use a ternary instead. You can then just create the component element with JSX like .
      Additionally, if you use TypeScript, you can create a union type for each variant through inference:
      type ComponentVariant = keyof typeof componentVariant;

  • @mishanep
    @mishanep ปีที่แล้ว

    And what about creating JSX and storing it as a value?
    I lot of time I saw code like this:
    const Component = () => {
    const header = ...
    const footer = ....
    return (
    )
    }

  • @thehangover4985
    @thehangover4985 ปีที่แล้ว +1

    Incredible video ! Explained very nicely!

  • @giovannitonussi3746
    @giovannitonussi3746 ปีที่แล้ว +4

    Amazing content as always. Ive made #1 and now not only I know it is wrong but most important I know WHY it is wrong, which is what I love about this channel. Thanks my friend.

  • @ChillAutos
    @ChillAutos ปีที่แล้ว +7

    These videos are so good. Not clickbait. Legitimate issues we all see all the time / have made ourselves. Great in depth concise explanations, with real world examples not some contrived scenario that never happens. Amazing as always.

  • @sujithgnth
    @sujithgnth ปีที่แล้ว

    This is gold, I never used this pattern but good to know :)

  • @Luxcium
    @Luxcium ปีที่แล้ว +2

    These videos are highly addictive I must admit 🎊 😅 🎉

  • @beepdotboop
    @beepdotboop ปีที่แล้ว +4

    I've seen some of these mistakes in some codebases I've worked on. Git blame showed that it typically is a backend engineer dabbling in the FE and bringing along patterns they are used to. Great video and happy new year!

  • @jr-hp7er
    @jr-hp7er ปีที่แล้ว +3

    First comment.. huge fan of yours 😉

  • @ChristofferLund
    @ChristofferLund ปีที่แล้ว +5

    Luckily haven't done or come across these myself, but glad to see you spread awareness since it seems like some are taught this

  • @23luski23
    @23luski23 ปีที่แล้ว +4

    it's hard to imagine why someone would do the mistake #3, it's so crazy! ;)

    • @jherr
      @jherr  ปีที่แล้ว

      :shrug: I've seen all kindsa weird stuff.

  • @typingcompetition
    @typingcompetition ปีที่แล้ว +1

    But who EVER would use a Component as function?! 😲 And defining components inside components?! What developers are out there🤨

  • @jasonfavrod2427
    @jasonfavrod2427 ปีที่แล้ว +3

    Thank you for making this video. It's one of those things in React development that I'm always finding myself un-teaching people. Now, I can just point them to this video!

  • @FS-il7fd
    @FS-il7fd ปีที่แล้ว +3

    Hi Jack. Im following you for a while now. Thanks a lot for all those awesome tipps. Im a principal web dev here in germany and I really have to stress the point that every react developer should drasticly reduce "logic" inside components in general. I highly recommand to "do nothing inside jsx"". Always go for jsx-compositons at last (codewise inside your Component definition). Just reference variable inside jsx. Even your eventHandlerFactories etc.. Just wast another well-named const to expain what going on, drop it inside jsx and get around most of the footshots. Cheers!

  • @yamelamadorfernandez7416
    @yamelamadorfernandez7416 ปีที่แล้ว +4

    Yes! I not only made those mistakes during my React learning curve but also now that I am a bit mature my eyes have opened and I am able to identify those mistakes during code reviews. I love your videos Mr. Herrington, very educational content.

  • @suganya32
    @suganya32 ปีที่แล้ว +1

    This video is really helpful. Thanks for posting.Could u post a video for react redux hooks into webcomponent?

  • @francis_n
    @francis_n ปีที่แล้ว +3

    I literally got the "Rendered more hooks than previous render" for the first time ever at work today doing something slightly different. Took me some googling to figure it out. I was rendering a component by invoking it as a function and any presence of a useState hook within the component spawned the error and took down my app. Jack made this video today because he was reading my mind, haha. I also for the life of me cannot work out why anyone would do mistake 3. I'd really love to know where they learned that from. Great video Jack, very timely!

  • @rick9348
    @rick9348 ปีที่แล้ว +3

    These are the most bizarre mistakes i've ever seen, never have I come across anything like this xO

  • @quelchx
    @quelchx ปีที่แล้ว +1

    Happy new years Jack. Looks like you got your ears lowerd (my grandfather way of saying haircut)

  • @ky3ow
    @ky3ow ปีที่แล้ว +2

    3rd approach looks similar to `render props` pattern(look into react docs), which was popular in class components before hooks, probably people write this because its familiar? in class components you wouldn't need to care about renders because you would slap this `component` into class method, which do not get re-instanciated on every render

    • @jherr
      @jherr  ปีที่แล้ว

      Yeah, and in the case of render-props that's totally fine. This was just a div though. RenderProps might make a good video though.

    • @ky3ow
      @ky3ow ปีที่แล้ว

      @@jherr ik, maybe someone just so used that put them everywhere). Good video idea indeed, i've wondered for a long time how Headless UI expose their state until i randomly stumbled upon this pattern

  • @IceMetalPunk
    @IceMetalPunk ปีที่แล้ว +1

    I've never seen any of these in the wild, and I'm glad, because if I had I might have thrown up in my mouth a bit 😅

  • @wonjunjang3839
    @wonjunjang3839 ปีที่แล้ว +3

    Always with the high quality contents you are like my own senior-dev at my job Thank you

  • @doritoflake9375
    @doritoflake9375 ปีที่แล้ว +1

    Thanks for sharing this! I had no idea about 1. I often use that paradigm if I need to render a component conditionally. So I'll make a resolveComponent() function in which I am doing something to the effect of if() {return ...} else {return ...}. What is the best practicy way of handling these conditionals?

    • @jherr
      @jherr  ปีที่แล้ว +2

      Ternaries are the easiest way to do that.

    • @doritoflake9375
      @doritoflake9375 ปีที่แล้ว

      @@jherr I guess but then the code gets yucky with X ? Y : (Z ? A : B). :D

    • @jherr
      @jherr  ปีที่แล้ว

      @@doritoflake9375 Sure, but you can use a simple sub-component for that. Or just drop the logic at the start of the component and set a local variable with the component to either render, or the component rendered with createElement (through JSX). Or as the result of a memo, or ... lots of options.

    • @pubuduperera6814
      @pubuduperera6814 ปีที่แล้ว

      @@jherr I do the same thing can you do a small video about how can we handle that senario without doing messy code with lots of ternary

  • @jeromealtariba7339
    @jeromealtariba7339 ปีที่แล้ว +14

    Hi, I usually do the second "mistake" only when components need to be created with forwarding Refs (often necessary when using Material UI embedded together with your own components or other librairies). It seems to me more obvious and easier to maintain when the "forwarded ref component" is defined in the same package as the "base" component used in the forwarded one. Especially in typescript when you need to define the good types or interfaces for both "base" and "forwarded ref" components. (Sorry if my english not that clear ;-) )

    • @Stoney_Eagle
      @Stoney_Eagle ปีที่แล้ว +3

      No need to apologize for your English skills mate, your English is good and perfectly understandable. 😉

    • @jeromealtariba7339
      @jeromealtariba7339 ปีที่แล้ว

      @@Stoney_Eagle thks

    • @michaelyabut5969
      @michaelyabut5969 ปีที่แล้ว +1

      Yes maybe I am not understanding the docs, but MUI and Bootstrap do #2 in their examples/components often

    • @thedamned87
      @thedamned87 ปีที่แล้ว +2

      @@michaelyabut5969 This. I think the biggest source of mistake #2 are the examples given by library creators - which mostly show "simple" usages. Combined with no or minimal knowledge in using React produces this "mistake". I've also encapsulated "private" components within the components myself at the beginning of my React learning path up until I fully understood how the "export" keyword is used and that I do not need to have one file per component (over-engineering).

  • @geforcesong
    @geforcesong ปีที่แล้ว +1

    you can write some complex logic with the 3rd mistake. maybe that's the only benefit

  • @bahaaka828
    @bahaaka828 ปีที่แล้ว +2

    Regarding mistake number 2.
    I do something similar to it but I am not sure if it´s falls exactly under the same umbrella (Looking forward to hear your opinion about it). But before I share the example I will tell you the "Why" we actually do this. We only do this in the Top level components (Like the root page component HomePage, EditPage, ..etc) Where in order to construct the page you have to add a lot of inputs, buttons, cards, and layout components grouped in some way or another (based on location within the page or visual hierarchy). These groups doesn´t seem to be a good use case to make a react component as they are not gonna be used outside of this page by any means. The resulting JSX of the page component will become so big in some Pages (usually the ones with many visual sections) where it is really hard to navigate through during code development or through code reviews. So What we opted for instead is the following.
    Instead of having the root page component rendered in this way:
    function MyProfileEditPage() {
    const state = useMyProfileEditPageViewModel()
    return



    .... Some other components needed to render the content of the homepage
    .... Which is gonna make this component JSX is too huge (400 - 500 lines and in some cases even bigger)

    }
    We do this instead:
    function MyProfileEditPage() {
    const state = useMyProfileEditPageViewModel()
    return
    {renderTopAppBar()}
    {renderBasicProfileCard()}
    {renderAdvancedProfileCard()}

    function renderTopAppBar(){
    return


    }
    function renderBasicProfileCard(){
    return
    ... some markup

    }
    function renderAdvancedProfileCard(){
    return
    ... some markup

    }
    }
    What we are trying to achieve with this approach is the following.
    1- Way better code reviews: The PR reader can see the top level overview of the page (How it´s structured in the exact order) and choose to navigate exactly to the section in the page where he is more interested in reviewing (using the function names renderXXX())
    2- Way easier code navigation within development: If there is a change that has to be done in a certain part in the page you can immediately tell where to go in the markup. In the example above if we happened to make changes in the Advanced Profile form and add a new inputs you can immediately navigate to it with the help of the names of these functions.
    3- No more prop drilling and extra boilerplate: In the example component there is a state object. If we happened to extract these "locally defined" functions outside of the Page component and make them a React component (In the same file without exporting them because that´s the main motive which caused this code design "pattern/issue" to exist) we would either pass down the state object as-is (aka the lazy approach but less boilerplate) or pass only the properties used in these small sections of the page causing us to write the props interfaces for each one of them (A lot of boilerplate). While On the other hand. In the "locally defined stateless" functions. We get rid completely of this problem because the state object is accessible and causes no issues.
    4- Finally and most importantly. Encapsulation of these (Group Components) which happened to exist only for the purpose which is constructing the different sections in a certain page.
    I hope in my comment that I addressed the "Why" behind this approach. But What I am honestly looking forward to hear from you is your opinion about it and what is the proposed alternatives (taking in mind the 4 points that we were trying to achieve).

    • @jherr
      @jherr  ปีที่แล้ว +4

      I've always done this as a set of components, so there would be a TopBar, BasicProfileCard, AdvancedProfileCard, etc. components, in the same file, but maybe not exported, or exported only in dev mode for unit tests.
      Addressing your points: #1, not sure that really has an impact on code reviews per se. #2, components are also functions, so if navigating to functions is easy, then it's just as easy with broken out components. #3, sure there is no prop drilling, but that also means that you have one mega component that manages all the state and everything re-renders even when it doesn't need to. #4, to me components are just as good of an encapsulation.
      Lemme offer some downsides. First, renderAdvancedProfileCard is a function not a component function, so it can't have its own state. Second, this single function is going to get absolutely massive over time and all of the hooks will have to be at the top, it'll read like Fortran. Third, dev tooling goes out the window with this. All of the awesome work put into props, and context, memoization, minimizing re-renders, etc. is thrown out with this renderNNN() approach.
      Yeah, I just don't see this approach as making the best use of the framework, IMHO. It feels like you are fighting against how the framework was intended to be used. I've certainly seen render functions in the past in small doses, but I wouldn't architect around their use.

    • @bahaaka828
      @bahaaka828 ปีที่แล้ว +1

      Thanks for honestly reflecting your thoughts on this approach.
      I will share your feedback with my team and see how we can improve from there.

    • @alkismavridis1
      @alkismavridis1 ปีที่แล้ว +1

      IMO, both creating new components and creating functions to decompose a big return statement are legit usecases.
      We use both for techniques for different reasons. I do not think any of them is wrong.
      Of course if things get massive, then we break down components and even create new files for them (I find this cleaner).
      When we need to give them their own state, again, new component is the way to go.
      If we want our dev-tools to treat those "fragments" as a new components, again, a new component is a way to go.
      Still, when our only goal is to break down a return statement into a more readable format, and not impact or complicate anything else, then function decomposing is a perfectly fine technique IMO.

    • @jherr
      @jherr  ปีที่แล้ว +2

      @@alkismavridis1 You do you, but IMO, the intention of React is to encourage small components that are easily reused and composed into larger structures. More or less following Brad Frost's atomic model of composition. The less that you use components the less you are using the framework, and at a certain point you would be better served by a templating library because you won't be getting enough value from the 142Kb of React lib that you are dropping on the page.

  • @faizansayyed3047
    @faizansayyed3047 ปีที่แล้ว +1

    In my previous team i have some seniors who used this type of code style and believe me components were huge, chunks of code in one file was a complete mess to do one simple change.

  • @joejazdzewski
    @joejazdzewski ปีที่แล้ว +1

    I see these implementations all the time and I have no idea, where they are taught. I have to break other developers out of using those practices

  • @anderssoderberg4421
    @anderssoderberg4421 ปีที่แล้ว +1

    + if you put components in another components a new instance of the nested component is created every time the prop changes, bloating the browsers memory for no reason

  • @stachbial
    @stachbial ปีที่แล้ว +2

    Hi, thanks for the video Jack! Good examples and argumentation, however I am curious what would be the best solution for the scenario, that I have encountered today (regarding the first mistake). Statically rendered Next.js app with some headless CMS. We created an Icons file importing all (about 60) different icon components that would be used anywhere in the project and exporting them as members of one "Icons" object, i.e.:
    const Icons = {add: AddIcon, exit: ExitIcon};
    where AddIcon and ExitIcon are the imported components. Most often called in JSX like .
    Let's say I have to render a particular icon based on some string (i.e. "iconName") received from CMS. My choice was writing it like this :
    {Icons.[`${iconName}`] && Icons.[`${iconName}`]()}
    Since those components do not carry any state and I am making sure the particular icon is not undefined, there should not be any serious effects of doing so. Nevertheless, after watching the video I wonder whether using the "top level API" like React.createElement would be better (I can see the benefit of controlling rerenders of the Icon component). Or maybe there is another, yet even better solution for implementing such a mechanism?
    Once again, thanks for the video as well as the answer in advance:)

    • @jherr
      @jherr  ปีที่แล้ว +1

      const IconComponent = Icons.[`${iconName}`];

    • @stachbial
      @stachbial ปีที่แล้ว

      @@jherr Thank You for such a fast answer. Yes, I can see that is a reasonable solution, however wouldn't it violate the very second rule of not creating components within components, as You mentioned in the video? Once again, thanks for the answer ! :)

    • @jherr
      @jherr  ปีที่แล้ว +1

      @@stachbial No, because you aren't creating a new component, you are just selecting an existing component.

    • @stachbial
      @stachbial ปีที่แล้ว

      @@jherr Oh, I get it now - the const just points to a reference, which is not called untill in JSX. Thank You very much for Your time!

  • @mahdijafaree5332
    @mahdijafaree5332 ปีที่แล้ว +1

    There we go ....
    here's Jack with another gr8 content!
    Thank you Sir! 🙂

  • @afuyewale5648
    @afuyewale5648 ปีที่แล้ว +1

    1 & 2 are relatable and understandable but for 3, I don't know why someone would do that.

  • @ilovelctr
    @ilovelctr ปีที่แล้ว +1

    Wow, Jack, this is truly amazing. But after watching this, I want to ask if the following practice is a bad one?
    Imagine that in the returned JSX paragraph of code, I have something like this: {showComponent && renderComponent()}.
    I've seen a lot of people do that, me myself included. I'm not sure if it's better to actually memoize this renderComponent function using useCallback? I mean, clearly the return value of this function will be JSX, hence the question about useCallback being useful or not. Thank you.

    • @jherr
      @jherr  ปีที่แล้ว

      There is a really good comment on this thread with someone advocating for extensive use on renderNNN() in a component as an architectural model and I give a lot of reasons why that isn't good. That being said, I think a simple renderNNN that's less than say, five lines, is probably fine.

  • @jeffery_tang
    @jeffery_tang ปีที่แล้ว +1

    i did components within components, no one taught me that, i did a lot of oop before and doing that kinda of encapsulation was out of habit

  • @Filipmalek1
    @Filipmalek1 ปีที่แล้ว +3

    You're the best, Jack!
    In terms of defining components within other component's module and/or function body - I saw it quite a few times but never got onto doing the same myself. Like you said, it bloats the component, makes it less performant (unless we use useCallback) and we're unable to reuse it/test it. I always stick to having these tiny functions as their own files even. I guess I started doing it way back in the beginning as it helped me understand React better.

  • @hienbui5793
    @hienbui5793 ปีที่แล้ว +1

    Actually I have already used the third one with switch case.
    Instead of using {something && } multiple time such as:
    {something && }
    {!something && }
    {something && something2 && render3/>}
    I think it's fine, it's my reference, because when using checking above, it's like although you already got the first render but it still check the another condition with nothing useful. so I use IIFE plus switch, for check condition then render only one that suits.
    If my way is bad or something wrong with it, I want to know.

    • @jherr
      @jherr  ปีที่แล้ว

      I think they are great. Though I do often find them hard to consume and know that I'm using them the way that the author intends.

  • @guillermocava3568
    @guillermocava3568 ปีที่แล้ว

    So coming from Vue to React, one thing I've been missing a lot are slots. Though the react paradigm is that "Everything is props", it can feel weird to have something like
    ...
    Though not guilty of the mistakes mentioned, I can see how perhaps when trying to reach for something like slots in react, those mistake could present themselves.
    as a side note, if anyone has some perspective on layouts and slots in react would love to hear them! 🙏

    • @jherr
      @jherr  ปีที่แล้ว +2

      I just used that prop element a few minutes ago. It's totally fine. As are renderProps. Though when passing functions to a component it's good to use `useCallback` for that as the function reference will change with each render if you don't and possibly break `memo`ed components, or components that use that render prop in their own dependency arrays.

  • @maacpiash
    @maacpiash ปีที่แล้ว +2

    I think I saw nested definitions of components somewhere in the Material UI documentation.

  • @haroldpepete
    @haroldpepete ปีที่แล้ว +1

    something that really scarme me right now if that i never seen those erros before and i could use them until this day because i know them, you know that each day i try to learn new things, and your brain mix good and wrong information, i would rather have not seen this video, what i've done

    • @jherr
      @jherr  ปีที่แล้ว

      I don't think that's necessarily a bad thing. It's fun to try out stuff that potentially crashes the framework you are using to test and understand its limitations better.

  • @ak-loz
    @ak-loz ปีที่แล้ว +1

    Ok..
    Where is your react course?
    I’m working my hardest to be a principle engineer.
    I aim to master react and everything JS, I believe you’re the person I should go to.

    • @jherr
      @jherr  ปีที่แล้ว

      th-cam.com/play/PLNqp92_EXZBJs6rKouX5U8-tWJgTLaeKv.html

  • @Stoney_Eagle
    @Stoney_Eagle ปีที่แล้ว +2

    I learned React from TH-cam and I have not seen these things, I didn't even knew that invoking a component was a thing 😅
    Do you know, and could you make a video on how to have performant rendering of a huge array of complex interactive components that are displayed in a css grid or flex?
    I've tried react window and a few others but they all break layout and are made for plain and boring spreadsheets.

    • @Hizbullla
      @Hizbullla ปีที่แล้ว +2

      Components are still functions that React has to call to render, so I get why people think it's ok, but it just seems like a massive over complication.

    • @jherr
      @jherr  ปีที่แล้ว +1

      Enough folks ask questions around rendering arrays correctly and efficiently that I should do a video on it.

    • @twothreeoneoneseventwoonefour5
      @twothreeoneoneseventwoonefour5 ปีที่แล้ว +1

      UseMemo or memo for help with rerenders(if you have them).
      Then lazy loading/pagination/infinite scroll.
      You never really need to render the entire huge array of complex interactive components all at once anyway. Render enough in the dom, have a search field or something(if applicable) and I think you are golden in most cases.
      Also layout breaking is probably your css skill problem, not really a react issue.
      If you still have problems after trying all of the above, your design choices are probably all wrong/over the place and you should probably rethink the entire structure of your project before it is too late.

    • @jherr
      @jherr  ปีที่แล้ว +1

      @@twothreeoneoneseventwoonefour5 There are good virtual table options out there as well that will only render elements as required. That being said, I wouldn't just go for that right away. If your tables or selects are searchable (as you suggest) or just naturally small, then just render them and don't worry about it. Re-renders aren't the end of the earth. React was literally designed to optimize re-renders.

    • @Stoney_Eagle
      @Stoney_Eagle ปีที่แล้ว

      @@twothreeoneoneseventwoonefour5 I appreciate you trying to help.
      I am talking about a "Spotify clone" where I need to display tracks that are from the "various artists" artist and they can exceed 100k (mine exceed 3k) if the user has a ton of songs from mixed albums. Ideally you can hide that artist but I don't have too if I can fix this.
      And about my "CSS skills" have you worked with any of the react virtual table packages? They work differently and will not work if your layout has scroll animation behavior when the "window" it creates is not the full size of the list 😉
      The problem I am facing is that react pushes one item to the dom at a time and not the whole list in one go, making the app stop responding until that has finished, memo is not going to help since there is no calculation required to display the items, it's only stitching object values together but include current song playing and should display logic based on the type of list.
      Maybe chunking the list with infinite scroll is an option, I will try that, thanks!

  • @maxs713
    @maxs713 ปีที่แล้ว +1

    Have you all met that developer that overcomplicates his code for no reason?

  • @HolgerStaubach
    @HolgerStaubach ปีที่แล้ว +1

    Thanks for the great video. I will check my code in regard of the second mistake. By the way. What is special with the browser you used. Its was ARC ?

    • @jherr
      @jherr  ปีที่แล้ว

      Yep, Arc.

  • @jotamodesto
    @jotamodesto ปีที่แล้ว

    One thing that I've seen that I find really bizarre is returning the entire JSX structure in one big useMemo, I've specially seen this in React Native, I don't know where people learned this.
    Another thing is I don't know if it's a mistake but I've used to do render functions in function components
    I've stopped doing this because of code readability, but I actually don't know if it has any performance problems.

    • @jherr
      @jherr  ปีที่แล้ว +1

      It's a high class version of a `_renderNNN()` nested function within the component. Like `_renderHeader()`. IMO the value of these render functions is dubious. Best just to use a component. Then if you need to memoize it, just wrap it in a `memo`.
      In the case of React-Native they are trying to make sure that they create new component instance as rarely as possible.

  • @dylanthony1
    @dylanthony1 ปีที่แล้ว +2

    You deserve a sub after this video. It’s explained so well and isn’t over explained. It’s the perfect medium.

  • @HasnainAli-uo2uw
    @HasnainAli-uo2uw ปีที่แล้ว +1

    Please Sir ! Make a full Course on Next.js with Typescript ...
    We really need it and it is not available on youtube ...Pleease sir.

    • @jherr
      @jherr  ปีที่แล้ว

      If I put it behind a channel membership would that change your mind? I'm thinking about creating a channel membership for some small amount and some content would be behind that so that I can fund the channel with the proceeds.

  • @montanaflynn1390
    @montanaflynn1390 ปีที่แล้ว +2

    Hi Jack, your videos are such a great resource!
    One thing I've been struggling with is hooks using other hooks data as arguments. I don't know what the best practice is for dealing with hooks return values possibly being undefined.

  • @marouaniAymen
    @marouaniAymen ปีที่แล้ว +2

    Thanks again for this channel, I did learn a lot form your videos. I have a question, concerning the first mistake. In reality I found myself invoking a component as a function but in this case because I found myself calling a switch statement to define the icon to display. In fact, the main component receives the type of info as prop (INFO, WARNING or ERROR) and inside, there is function that returns an icon component according to a switch based on this type.

    • @jherr
      @jherr  ปีที่แล้ว +1

      That's fine, that's not a "component", that's a helper function that returns a React.createElement result. As long as your helper function doesn't use hooks, or act like a component, it's fine.

    • @marouaniAymen
      @marouaniAymen ปีที่แล้ว

      @@jherr Thanks for your answer.

  • @Krzysiekoy
    @Krzysiekoy ปีที่แล้ว +2

    I was investigating the mistake number 1 with calling your component function instead of using JSX or createElement API. I understood the part about JSX just being a call to react.createElement under the hood.
    What I can't wrap my head around exactly is the fact the calling component as a regular function, seems to return JSX, too. I've played around this in code sandbox where I made a MyComponent that just returns a p tag with the text "hello".
    In the main Component, I've console logged both MyComponent() and and the results were almost identical. Both objects had properties such as type, key, ref, props, _owner, _store. The only difference between them was that the first had type: ƒ MyComponent() and the other one had type: "p".
    I then did a similar thing where I would conditionally show MyComponent() based on a hook value in the main App component. It didn't crash (just like your example) but then I added a hook to MyComponent and the app blew up (just like your example).
    The part that is "magical" to me is this: how does React convert a call to MyComponent() function into a hook. This is blowing my mind.
    In general I think that I understood the premise: you render a component with x number of hooks -> component re-renders -> react environment "notices" that the number of hooks in the component has changed -> this is no good, so crash...
    This is such a great video that gave me something to think about.
    I've also re-created this crash by simply declaring a second hook in the main App component conditionally (with ESLint yelling at me: "React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.") with a button that makes the condition true . This gives the same result/crash.
    So I guess the main lesson here in that React components must have the exact same number of hooks with the exact order in every single render. Though that "auto-hook" still blows my mind.

    • @jherr
      @jherr  ปีที่แล้ว +2

      The difference between Foo() and React.createElement(Foo, ...) is that you are telling React to instantiate Foo as a component and to have it control that portion of the VDOM tree. If you don't use React.createElement then to the extent that React knows anything about what you've done, it just looks like a custom hook if the function includes hook calls.

    • @Krzysiekoy
      @Krzysiekoy ปีที่แล้ว +1

      @@jherr Thanks, that is really interesting. I feel we are getting to some deep React stuff here :D

  • @anhdunghisinh
    @anhdunghisinh ปีที่แล้ว +1

    for some old lib i have to do the 2nd method. they don't have a component export

  • @pierluigiomargiancola7388
    @pierluigiomargiancola7388 ปีที่แล้ว +2

    Second mistake done few times.
    For example:
    - component container render a list of item component such that the first 3 items are rendered and of there are more than 1 left it will render a drop-down menu, otherwise it render the last item.
    - items receive some handlers cause they don't have logic
    - in the render of the container I have three places where I declare items and pass them the same props
    - what I did there, was using useCallback to define the item with the handlers inside the container.
    - nobody taught me that, I was just trying to DRY in the container component render
    Thanks for the great content and happy new year (⁠ ⁠╹⁠▽⁠╹⁠ ⁠)

  • @juanandresmezzera9304
    @juanandresmezzera9304 ปีที่แล้ว +1

    Is there a good pattern for unit testing components that are not exported from a module? Because, AFAIK, you'd still be unable to unit test them with the proposed solution

    • @jherr
      @jherr  ปีที่แล้ว

      If you really, really needed to hide them then you could have the components conditionally exported only if NODE_ENV isn't production. And then you can unit test the exported functions, but they are only exported when in dev or test.

  • @BHFJohnny
    @BHFJohnny ปีที่แล้ว

    I've seen helper functions inside of React component enclosed in useMemo, that only returned some static JSX. Feels not great, but ok to me.

  • @codewithguillaume
    @codewithguillaume ปีที่แล้ว +1

    Good to see you again 🎉

    • @jherr
      @jherr  ปีที่แล้ว +1

      Great to be back. The holidays were cool. But rollin' videos feels real good.

  • @und0
    @und0 ปีที่แล้ว +1

    biggest mistake here is not using TypeScript lol

  • @Weagle1337
    @Weagle1337 ปีที่แล้ว +1

    12:49 Oh my god, why?, There are people that code like that?

  • @artemperchyk7776
    @artemperchyk7776 ปีที่แล้ว +1

    Hey what's the vs code extension that showed the warning about more hooks than the previous render right in the IDE?

    • @jherr
      @jherr  ปีที่แล้ว

      Console Ninja

  • @ToddDunning
    @ToddDunning ปีที่แล้ว +1

    I can give you years of material for these in just one of my repos and I’ll only charge a monthly subscription fee

    • @jherr
      @jherr  ปีที่แล้ว +1

      One man's trash... :)

  • @akasadulloh3393
    @akasadulloh3393 ปีที่แล้ว +1

    Thanks so much! Now I understand why I blow up my react app when it gets bigger 😂

  • @mishanep
    @mishanep ปีที่แล้ว

    And what about creating JSX and storing it as a value?
    I lot of time I saw code like this:
    const Component = () => {
    const header = ...
    const footer = ....
    return (
    )
    }

  • @dawidzajac34
    @dawidzajac34 ปีที่แล้ว +1

    About mistake #3. Is it the same as defining function outside the return statement and then calling it? Please consider this example:
    ```
    return (
    {(() => Example)()}
    )
    ```
    vs
    ```
    const getHeadline = () => Example;
    return (
    {getHeadline()}
    )
    ```
    Of course this is overcomplicating things in this particular case but sometimes this approach works really well (e.g. complex conditionals deeply nested inside the return statement - instead of chaining ternary multiple times I find it better to create IIFE and write if statements inside which I find way easier to read). I haven't noticed any difference in react-devtools components tab - it's not defining a component but a function which returns JSX. As far as I remember I've seen the second approach (defining get-jsx functions outside the return statement) taught by Kent C Dodds but I believe both of them are the same.
    Correct me if I'm wrong. Any thoughts are more than welcome!

    • @jherr
      @jherr  ปีที่แล้ว +1

      It does work, that's true. And it is better than the example shown because the function is titled `getHeadline` (or often `renderHeadline`) which is helpful. And many people have commented about this if you go through the comments. Question is, why is this better than just having ``. If `getHeadline` needs state then those hooks would probably go in the parent component function and get passed as closure values, which, isn't really using React.

    • @dawidzajac34
      @dawidzajac34 ปีที่แล้ว

      @@jherr Good point!

  • @ShellBryson
    @ShellBryson ปีที่แล้ว +1

    Honestly, first time I've seen components being nested the way you describe, and entirely agree that it'd result in bloated, leaky code.

  • @ogreeni
    @ogreeni ปีที่แล้ว +2

    Another great video Jack! Thanks for diving into advanced topics that no one else cares to talk about.

  • @ASTROMAN21
    @ASTROMAN21 ปีที่แล้ว +1

    Just want to tell you that your videos are 💯!
    Way to go!!

  • @tshephangm13
    @tshephangm13 ปีที่แล้ว

    Learning how to code from Kevin De Bruyne, gold!!!

  • @RmNrIHRoZSBDQ1AK
    @RmNrIHRoZSBDQ1AK ปีที่แล้ว +1

    Never seen anything like it. I guess #1 could happen if you had an object mapping props to components and you'd want to pull one out dynamically. You can't do something like (where 'cat' is from a variable) so the "solution" you might be inclined to use would be {Animal['cat']()} ? Dunno. For those wondering, you do it like this: const MyAnimal = Animal['cat']; return

  • @mimitch123
    @mimitch123 ปีที่แล้ว +1

    I first learned React using class components, and (referring to mistake 3) is the idea of having render functions defined in the class, and calling them inside the main return(JSX). It took me a minute to get over this tendency once functional components became standard, and I'd never do that now.

  • @christucker9566
    @christucker9566 ปีที่แล้ว +2

    That last one can’t be real, that’s made up for content right?

  • @panpanzhang
    @panpanzhang ปีที่แล้ว +1

    Why doesn’t react allow different number of hooks to be called between each render?

    • @jherr
      @jherr  ปีที่แล้ว +1

      Because we don't identify hooks by name. There is no name associated with `useState()` just the variables we assign them to, which React doesn't know about. So all React has to go on is the call order and index.
      So if you call a different number of hooks between each render then what happened? Did you remove one in the middle? Or add one at the start? Or drop one at the end? It's impossible to know. So... you always have to call the same number of hooks (except for the "use" hook).

  • @MRmoogle10
    @MRmoogle10 ปีที่แล้ว +1

    Awesome video!

  • @christopheanfry2425
    @christopheanfry2425 ปีที่แล้ว +1

    Would love to see a video with nextjs13 and how to deal between server and client components when sometimes you need states after fetch fro exemple. Thanks really nice video, very helpful

  • @zsytssk5176
    @zsytssk5176 ปีที่แล้ว +1

    I never see these three mistakes. these all feelled awkward to me.

  • @MsPrakhar12
    @MsPrakhar12 ปีที่แล้ว +2

    very cool and detailed explanation 💯

  • @acasta
    @acasta ปีที่แล้ว +1

    I've seen #1 + #2 different to your #3. Where one big component is created and contains all the state & data, smaller 'components' are created in that component scope that are just functions using data / changing state & returning JSX, that are then invoked in the big component return.
    I think it's to access data/state of the one big component, and not need to create a new component + file then deal with getting access to the data, state & state update functions (via prop drilling / context / a store).
    I'd be keen to understand how you handle handle bigger components that share data/state + update functions with their children.

    • @jherr
      @jherr  ปีที่แล้ว

      Context, or a state manager, I've done a lot of videos on that. Just dig on into the collection. :)

  • @Doodely654
    @Doodely654 ปีที่แล้ว +2

    I feel that for mistake #3 a lot of people continually are told to isolate anything that might be reused (heading components aren’t too uncommon) but they try doing this over-optimization stuff out the gate instead of first working towards the presentation they want, then breaking down reusable parts

  • @NiceChange
    @NiceChange ปีที่แล้ว +1

    Thanks. So simple and effective

  • @amol_
    @amol_ ปีที่แล้ว

    Second Problem: If we have conditional components then moving focus from one element to next element in flow does not work on click of tab because it rerender and lost the focus.
    CONDITION COMPONENTS I means like selecting from drop-down and then displaying input field and in this case if drop-down is render like problem two then navigation from tab will not move focus from drop-down to next input field.

  • @renatobesson
    @renatobesson ปีที่แล้ว +1

    I'm in love with you. Your explanation is so easy to understand. Congrats and thanks for this awesome video!

  • @tamantaman
    @tamantaman ปีที่แล้ว +1

    Amazingly helpfull. Thanks.

  • @MrMudbill
    @MrMudbill ปีที่แล้ว +1

    I had no idea you could invoke components directly like in #1, but also no idea why you would do that. It felt scaringly wrong and dangerous from the beginning.

    • @jherr
      @jherr  ปีที่แล้ว

      Nothing should be scary, but, yeah, don't do it.

  • @recepciftci2642
    @recepciftci2642 ปีที่แล้ว +1

    I didn't knwo component nesting was that bad. Thanks for this awesome video. Please keep posting videos like this

  • @MsNarrow
    @MsNarrow ปีที่แล้ว +1

    Woah the third mistake is thoroughly complicated by itself. Thanks for sharing these previous mistakes as well , I'm a newbie into the world of web development and It's much appreciated to share this sort of material. Thanks and greetings from ARG :)

  • @Dusty-o4t
    @Dusty-o4t ปีที่แล้ว +1

    How is the "Rendered more hooks than during the previous render." error displayed in vscode? Is it a vscode extension?

    • @jherr
      @jherr  ปีที่แล้ว +1

      Yes, Console Ninja. It's free.

    • @Dusty-o4t
      @Dusty-o4t ปีที่แล้ว

      @@jherr Thanks! This is great!

  • @xinaesthetic
    @xinaesthetic ปีที่แล้ว +1

    So the third thing… I feel like it’s pretty common to map over something, with an anonymous closure for each element. Now, if that nested component gets complicated or particularly as as soon as it needs to deal with some internal state, then it seems necessary to factor it out, but how bad is it really otherwise? It seems like a first pass of getting the scaffolding together might often involve that, and there are probably cases where it’s unnecessary to change.

  • @adtc
    @adtc ปีที่แล้ว

    I can't think of why anyone would try to make these mistakes in the first place. Maybe because my thinking is more object-oriented than functional, that I can't conceive doing it myself. Lol

  • @BenjaminSolum
    @BenjaminSolum ปีที่แล้ว +1

    I usually see the 2nd mistake with CSS-in-JS frameworks like styled-components. A simple example being the below where `StyledDiv` could/should be defined outside of the containing component.
    ```
    function Cmpt() {
    const StyledDiv = styled.div` color: blue; `
    return Blue Text!
    }
    ```

    • @nivaldolemos5280
      @nivaldolemos5280 ปีที่แล้ว +2

      styled-components warns against this practice in the FAQs, under the section "Why should I avoid declaring styled components in the render method?"

  • @AlexRudOy4ik
    @AlexRudOy4ik ปีที่แล้ว

    I'm using 3 in cases i need switch case.
    For example you have multi-step form.
    Outer component has state with step number, then in jsx
    {(() => {
    switch (step) {
    case 1:
    return
    case2:...
    }
    })()}
    this is analogue of having long sequence of
    {step === 1 && }
    {step === 2 ....

  • @DanielNistrean
    @DanielNistrean ปีที่แล้ว +1

    Hi @Jack. I recently started working on a medium size corporate project. They use one single context as global storage for entire app. They started to have performance problems. I urged them to switch to a proper storage solution, like react-redux. But the technical lead and bussiness people oppose because of the possible bugs that this will cause. How to convince them to do the right thing ?

    • @jherr
      @jherr  ปีที่แล้ว

      Maybe there are ways to improve it without changing over entirely?
      th-cam.com/video/ZKlXqrcBx88/w-d-xo.html

  • @OryginTech
    @OryginTech ปีที่แล้ว +1

    Great video as always. Super helpful

  • @monarchgam3r
    @monarchgam3r ปีที่แล้ว

    i use Arc too, please please please how can i deactivate debugging mode when dev tools is open, right now i cant use arc when working anymore cuz almost everytime i refresh something invokes the debugger and blocks execution
    please help