UseState: Asynchronous or what?

Sdílet
Vložit
  • čas přidán 3. 08. 2024
  • 👉 React Advanced: reactadvanced.com/
    👉 15% off on hybrid access to React Advanced! ti.to/gitnation/react-advance...
    👉 15% off on remote access to React Advanced! ti.to/gitnation/react-advance...
    👉 Practical Module Federation Book: module-federation.myshopify.c...
    👉 No BS TS (The Book): no-bs-ts.myshopify.com/
    👉 I'm a host on the React Round-Up podcast: devchat.tv/podcasts/react-rou...
    👉 Don't forget to subscribe to this channel for more updates: bit.ly/2E7drfJ
    👉 Discord server signup: / discord
    👉 VS Code theme and font? Night Wolf [black] and JETBrains Mono
    00:00 Introduction
    00:30 The Basics
    01:14 React Advanced Sponsorship
    02:12 Basic React State/Rendering Flow
    10:10 Fixing the Async "Problem"
    15:20 What have we learned
    16:30 Outroduction
    #reactjs #react18
  • Věda a technologie

Komentáře • 268

  • @pim8268
    @pim8268 Před rokem +116

    What a teacher. Such in depth concepts explained in such a simple way. This is why CZcams is important for us developers... Thank You Jack!

  • @tthiagolino8
    @tthiagolino8 Před rokem +51

    The new react documentation does not recommend using a useeffect to change the value of a state based on changing another state, as useefect only runs after rendering, which would result in more renders than desired (many more depending on how many states depend on the change of other states exist in your code).
    The recommendation is that a comparative state be created and that the reactive statemant be done normally in the render cycle within an if comparing the main and comparative state
    This recommendation is on the You Might Not Need an Effect page in the new documentation

    • @jherr
      @jherr  Před rokem +15

      Good point! That's why I prefaced the useEffect with saying that in this case you don't need the useEffect.

    • @bastek338
      @bastek338 Před rokem +1

      Can you send here a link to the example that you refer to? I mean ref to the new react documentation and example you mention above.

    • @jherr
      @jherr  Před rokem +5

      @@bastek338 beta.reactjs.org/learn/you-might-not-need-an-effect

    • @DisturbedNeo
      @DisturbedNeo Před rokem

      That documentation says (paraphrasing slightly) "While a component is visible, you want to keep results synchronized with data from the network. This is why it’s an Effect."
      I think in this case the useEffect is correct, but what the documentation recommends is ensuring you use the cleanup function of useEffect to avoid race conditions. I would, however, personally recommend using an AbortController rather than a boolean to handle this properly.

  • @jherr
    @jherr  Před rokem +23

    The variable going to setSearch should be `evt.target.value`. My bad on that one. Clearly the steps labelled "manual" and "Jack" in my workflow on these animations need some work. 😂

    • @vigneshwarrv
      @vigneshwarrv Před rokem

      Great Explanation Jack🙌

    • @dhavall08
      @dhavall08 Před rokem

      Can you please explain why you had to use currentTarget instead of target?

    • @jonisapp
      @jonisapp Před rokem +2

      @@dhavall08 currentTarget points to the dom element on which you have attached the event. target points to the element which triggered that event. That difference exists because of how events are propagated through the dom tree.

    • @PhilipAlexanderHassialis
      @PhilipAlexanderHassialis Před rokem

      Quick question though: on the useEffect version of the code, you say that during the initial render, useEffect runs and checks the dependency array to see if there are any differences in the dependencies and then sees the search value to be undefined thus performing the check. Since the useEffect declaration itself captures the value at the moment of render and the first time the `search` comes into existence is as an empty string, why would useEffect consider it as undefined during the dependency diffing check?

    • @jherr
      @jherr  Před rokem +1

      @@dhavall08 Force of habit.

  • @xc13z829
    @xc13z829 Před rokem +9

    Prior to this video, I conceived of useState working as follows:
    1. I create a component with something like const [variable, setVariable] = useState("");
    2. React uses Elves and Unicorns to manage this bit of state in some magical kingdom far away.
    3. The React Faeries and Nymphs bring this bit of data back from the magical kingdom and re-render the page producing something pretty on a computer screen.
    Apparently I was wrong.
    Jack, all kidding, aside, THAT WAS THE BOMB!! It is difficult to find anyone teaching these concepts with the depth that you do. THANK YOU!

  • @ilovelctr
    @ilovelctr Před rokem +16

    This video is very informative, as are Jack's other contents. Somehow this also explained why most things are defined as constants in a React component, because within one render cycle, they will never mutate. So it makes perfect sense to have them as constants. Once the state setter gets fired, and the current excution context gets to its end, you'll engage the next render cycle, where these state constants have new values, which are fresh ones coming from the V-dom 'variables'. So the constants are never mutated, but renewed with new cycles.

  • @jorge7139
    @jorge7139 Před rokem

    This was super enlightening. Understanding what React does under the hood helps a lot when structuring code. What a simple and eloquent way of guiding us through it. Thanks a lot!

  • @vatsalyasinghi438
    @vatsalyasinghi438 Před rokem +2

    Thank you sir. Being long term Angular developer, I have been trying to learn React and its workings.. This video has been quite insightful. Loved the in-depth explanation .. Thank you again and looking forward to more such video !

  • @user-ku2sn1wz1c
    @user-ku2sn1wz1c Před rokem +1

    This video just made my day. Thanks a lot for such great concepts!!!

  • @SumitKumar-tw4qe
    @SumitKumar-tw4qe Před rokem +5

    I might have focused more on the struggling squirrel in the background 🐿.

    • @alain_laroche
      @alain_laroche Před rokem +1

      🤣Was about to comment the same thing 🤣

  • @tayloratheo
    @tayloratheo Před rokem +2

    Great first sponsor! 👌🏾
    And helpful video as always 🔥

  • @pupfriend
    @pupfriend Před rokem +1

    Awesome! Thanks Jack. Appreciate you sharing your knowledge with us. 👍

  • @jjrise
    @jjrise Před rokem +3

    I have grown to love this channel. I really appreciate that Jack hits on these theory based topics (for lack of better words?). These are super helpful to React devs of all skill levels. Thanks again!

  • @elhaambasheerch7058
    @elhaambasheerch7058 Před 6 měsíci

    One of the few people who go into depth in the era of fancy abstractions, didn't even know this problem existed. Thanks for this!

  • @wunshon
    @wunshon Před rokem +2

    As always, really helpful content of react depth knowledge, thank you Jack!

  • @hameedpilot
    @hameedpilot Před rokem +1

    Lovely and informative one... Thanks sir!!

  • @mrjebbar
    @mrjebbar Před rokem +1

    Subscribed. You my friend are a legend and you've got a new fan. Excellent video. Please keep them coming. Very clear and very helpful

    • @jherr
      @jherr  Před rokem +1

      Thank you so much! Happy to have your sub!

  • @ofirlevy3682
    @ofirlevy3682 Před rokem +1

    Your videos are the best!!
    And as you say in the begining setState
    Doesnt return Promis

  • @eminm6383
    @eminm6383 Před rokem

    Even though I knew how to implement these, was not 100% confident how things were working under the hood and man, You have made these details look so easy to understand.

  • @dieteroberkofler4342
    @dieteroberkofler4342 Před rokem +1

    Probably one of the best explanations of useState i’ve ever seen

  • @_hugo_cruz
    @_hugo_cruz Před rokem +1

    Thank you Jack. This is really the first lesson that every programmer interested in React should learn.

  • @gendash
    @gendash Před rokem

    A crucially important concept, very well explained.
    Huge thanks, Jack!

  • @michaelrooze278
    @michaelrooze278 Před rokem +5

    great vid. quick correction, the diffing algorithm does not compare the virtual dom to the real dom, it compares the virtual dom to the previous virtual dom.

  • @dave7038
    @dave7038 Před rokem +1

    Thanks! I'm just starting with React and these videos are very useful!
    Also, I enjoyed watching your squirrel feeder in the background :D

    • @jherr
      @jherr  Před rokem +1

      The squirrels are very cheeky.

  • @Gangbuster74
    @Gangbuster74 Před rokem +1

    You are great, I mean people just create tutorial projects, but never explain in-depth, but you are backing us developers like us

  • @shashikantmarskole
    @shashikantmarskole Před rokem +1

    thank you Jack , nicely explain it...

  • @0xVantwoutMaarten
    @0xVantwoutMaarten Před 9 měsíci

    I love the state setter explanation in terms of newly registering of the state, so that setting does not changing the current state value but only makes a copy of the previously registered state.

  • @KresimirKatusic
    @KresimirKatusic Před rokem +1

    Excellent teacher, great video, thank you

  • @Bbehemothh
    @Bbehemothh Před rokem +1

    So glad that youtube recommended this!

  • @matheussunderhus9421
    @matheussunderhus9421 Před rokem +1

    What do we learned? That you videos are awesome! Thanks for your hard work. Best channel to understand and not copy paste things.

  • @hangtran4863
    @hangtran4863 Před rokem +1

    i love your background so much, beautiful nature

  • @jampy42
    @jampy42 Před rokem

    Just yerterday i had this exact issue at work and couldn't solve it, thanks to this video i finally get it to work, thank you very much!

  • @abdullahrafique2883
    @abdullahrafique2883 Před rokem +1

    Hey Jack thanks so much for this awesome guide.
    Can you please share any resource where we can read more about this?

  • @criticalthinker88gis13
    @criticalthinker88gis13 Před rokem +1

    This is what I have been doing, but I thought I was not supposed to. So happy I can continue to do this, because to me it seems like the most logical way.

  • @walterlol
    @walterlol Před rokem +3

    Lenz Weber is an awesome guy. Helped me instantly in a question about redux RTK.

  • @DjLeonSKennedy
    @DjLeonSKennedy Před rokem +1

    No one could explain better, thanks!

  • @serjio8781
    @serjio8781 Před rokem +1

    I'm a fan of yours now, sir. Great stuff.

  • @fmictsang8874
    @fmictsang8874 Před rokem +1

    I want to hit the like button multiple times. This video explains the concepts very well.

  • @emilito4
    @emilito4 Před rokem +1

    This is a really nice example and explanation 👐🏼. Maybe it's out of the scope of the video, but I'm thinking that it's also a nice example to show how an AbortController would be useful to abort the request and prevent undesired/useless rendering when the component unmounts or the user types several characters within the input field (since each character will trigger a re render).

  • @randomforest_dev
    @randomforest_dev Před rokem +1

    good explanation!

  • @allaithbitar1199
    @allaithbitar1199 Před rokem +1

    Holy knowledge 🔥
    God bless your effort 🖤🔥

  • @emreozgun3846
    @emreozgun3846 Před rokem +2

    this guy is a fucking wizard.

  • @b0tm0de
    @b0tm0de Před rokem +1

    Thank you.

  • @mutantgaming8331
    @mutantgaming8331 Před rokem

    Hey Jack, This video really helped to understand the flow better. But i feel it would we easier to understand if you show the output in the console along the way. 😃

  • @robertminardi4268
    @robertminardi4268 Před rokem +2

    I would love to be able to "Think in React", but there aren't many tutorials or tools that can assist with this. That I know of anyway. I have the React browser plug-in, but maybe I don't know how to use it for this purpose. It would be great to have a tutorial that did what this tut did, but in an interactive way. How about a "Think Reactly" series where we do deep dives into all the main react topics?
    BTW you're awesome!

    • @jherr
      @jherr  Před rokem +1

      Thank you, and honestly, as soon as I said that, I was thinking the same thing as you.

  • @bythealphabet
    @bythealphabet Před rokem +1

    Sponsors Yoohoo!!!!!
    good work Jack!!

  • @H4KnSL4K
    @H4KnSL4K Před rokem +1

    Thanks!

  • @MohamedNasser1
    @MohamedNasser1 Před rokem +1

    Thanks! You're the greatest

  • @mrSargi7
    @mrSargi7 Před rokem +1

    Best React channel in the whole youtube!

  • @djaalabahmed2038
    @djaalabahmed2038 Před rokem +2

    Great Jack 👌👌

  • @karangill2065
    @karangill2065 Před rokem +1

    I'm Amazed!

  • @robertrocha7216
    @robertrocha7216 Před rokem +1

    Great videos love your channel. Can you do videos on redux, router and usecontex?

    • @jherr
      @jherr  Před rokem +1

      useContext coming up. redux later on an upcoming freecodecamp video.

  • @WomboBraker
    @WomboBraker Před rokem +1

    thank you

  • @ebrelus7687
    @ebrelus7687 Před rokem +1

    proper tempo for learning 👌

  • @Johnny-rn8fb
    @Johnny-rn8fb Před rokem +1

    another awesome video

  • @krumbo
    @krumbo Před rokem +1

    Wow good stuff, where have been before?

  • @florianbopp187
    @florianbopp187 Před 6 měsíci

    9:26 technically we are not calling setResults here right. We decided against passing an anonymous function to just pass the setResults function instead. The function is then executed by the us runtime when the promise resolves.

  • @BezzantSam
    @BezzantSam Před rokem +1

    Congrats on the sponsor

  • @ThienNguyen-do4eo
    @ThienNguyen-do4eo Před rokem +1

    I did stuck with this bug sometimes when coding a pet project in the past, just recognized it after working for about half of year 😂

  • @amans6504
    @amans6504 Před rokem +1

    this is incredible, im smashing my head on this issue for long and never had a clear explanation of how it actually works, thanks for that jack

  • @rorycawley8334
    @rorycawley8334 Před rokem +1

    What a great demo to show why redux is needed, i.e. to avoid a total mess of a React component with useEffect. Avoid useEffect.

  • @luiscode92
    @luiscode92 Před rokem +1

    wowww, thanks

  • @mihaimanole2643
    @mihaimanole2643 Před rokem +2

    4:37 “... it’s going to capture the value of that state at that time” it’s in behaviour true in this case but JavaScript closures or functions never capture the value of a variable. Here the input element attribute onChange will get a new function (closure) every time Search is executed. Every that function has a different scope with the value of that state at that time.
    Anyway here are not variables but constants.

    • @jherr
      @jherr  Před rokem

      That is correct. And the new closure that is generated each time will have a captured value for `search` at the time of its creation.

    • @mihaimanole2643
      @mihaimanole2643 Před rokem

      Writing this notice made me meditate more on JavaScript behaviour. I felt compelled to warn that closures in JavaScript don’t capture the value of a variable at the moment of definition. Although JavaScript evolved and what I said is not all true: for constants captured by a closure, the value at the moment of definition is the same with the value at the moment of invocation.

  • @masterj1081
    @masterj1081 Před rokem +1

    Hi Jack, Thank you for this great content. If you let me suggest a topic for future content. I would point to the state management patterns in react,. Out of my experience I use state manager like zustand, but then I ended up forcibly passing props to child components, for example I want to use "results" state in different component, the question should I create temp global state or pass the prop. by doing so, I have no idea if I am build the app following a good practice. Thanks you.

    • @jherr
      @jherr  Před rokem +3

      I'm working up some content for a complete crash course on React state management for freecodecamp. Should be out in a month... or two... freecodecamp videos are a lot of work.

    • @masterj1081
      @masterj1081 Před rokem +1

      @@jherr I appreciate your effort, providing great knowledge.

    • @nimeshvaghasiya1663
      @nimeshvaghasiya1663 Před rokem

      @Master J @Jack Herrington currently, I have used to useExternalStore from czcams.com/video/4MmmlWwlST4/video.html by jack to have global state management.

  • @matttamal8332
    @matttamal8332 Před rokem +1

    The name 'React' to me signifies that something happens in reaction to something else. The base level is a component's render function re-executing whenever it's state/props change. The amazing thing about hooks is that they brought this paradigm to the state machines as well. We can now manually define the dependencies for functions & state objects. This granular control is fantastic and lets you basically do anything you want with just the base few hooks (useState, useEffect, useMemo, useCallback).
    I think the idea of closures and the 'snapshot' state of variables at definition time is one of those concepts that eventually just clicks once you do React and functional programming enough.
    Great explanation about the inner workings of useState though! I wonder if the internal state array, is of indefinite length or is just a tuple with the prev & current state. Will probably have to look at the source code.

    • @jherr
      @jherr  Před rokem +2

      Indefinite length but after the first render all subsequent renders have to have the same number of hooks.

    • @matttamal8332
      @matttamal8332 Před rokem

      @@jherr That makes sense and is probably the main constraint behind hooks having to be at base level too

    • @jherr
      @jherr  Před rokem +1

      @@matttamal8332 We don't provide any distinguishing meta-data to `useState` or `useReducer`. We don't name the data. So React has no way to distinguish which state is which outside of the order of declaration. We could name them, but honestly, I think most folks probably believe that React somehow knows that `const [orders, setOrders] = useState(...);` is "orders" somehow, when it knows nothing of the sort.

    • @matttamal8332
      @matttamal8332 Před rokem

      @@jherr Is this because React simply doesn't need to do it? Since the values are tracked in an array, it doesn't need to check against a copy, so it doesn't really need to be named as long as the order is the same.

  • @kmylodarkstar2253
    @kmylodarkstar2253 Před rokem

    Amazing video Jack, thanks!. A quick question, I remember used to trigger a class component state update from devtools with the $r.setState, E.G "$r.setState({message: 'Hello world!'}. Now I only see some $r.hooks array but don't know how to do this update. If you have any idea will be appreciated.

    • @jherr
      @jherr  Před rokem +1

      I don't personally try to trigger re-renders from devtools. So maybe someone else can offer a suggestion.

  • @DisturbedNeo
    @DisturbedNeo Před rokem

    A better way to think of the "setState" function is as "queueUpdateToStateForNextRenderWithValue", but that's kinda verbose so I get why the React team went with "setState"

  • @aseemanand1
    @aseemanand1 Před rokem

    Can somebody explain me how did the fetch come into picture at 8:45 as mentioned in this video? I thought fetch will only get called when onChange will get executed and onChange is only executed when user types any key.

  • @amanali9501
    @amanali9501 Před rokem

    Plz make a video on sequence of multiple useEffect

  • @osirri
    @osirri Před rokem +1

    if an older fetch is slower than a newer fetch, the older fetch's result will be set as state. needs an "isLatest" boolean that is set to false in the useEffect's return method, and check if this fetch is the latest in the fetch-then

    • @osirri
      @osirri Před rokem +1

      saw that someone else commented this already. ignore

  • @AsakuraAvan
    @AsakuraAvan Před rokem

    so the setSearch function of the array [search, setSearch] doesn't actually directly change the value of the search variable. It modifies the array within useState(), which triggers the Search function to render again, and that updates the value of the search variable of the [search,setSearch] array. Am I understanding this correctly?

  • @VikasTalksTech
    @VikasTalksTech Před měsícem

    where can i know more the control flow in js

  • @smash3689
    @smash3689 Před rokem +1

    Unbelievable! I've been looking for this information lately and this comes up!!! I've been guessing that it might be utilizing microtask, but thought that it didn't make sense when I looked at how it behaves when being used actually inside microtask queue with other promise resolves
    10:40 one quick question though. if i wrapped the setSearch with flushSync, would the console log be the updated state?

    • @jherr
      @jherr  Před rokem +1

      The state would be updated, as would the DOM, but the local value would still just be the copy from before.

    • @smash3689
      @smash3689 Před rokem

      @@jherr thank you!🙇‍♂ couldn't find any clear answer to this question anyware

  • @fredbluntstoned
    @fredbluntstoned Před rokem +2

    What is happening with those squirrels in the background?

  • @ahmedawji846
    @ahmedawji846 Před rokem

    Thank you for the great explanation, however, I'm a bit concerned about the application's flow. When the user hits a keystroke for the first time let's say he hits the 'F' character, does the fetch function runs with an empty string for the first closure then it runs again with the 'F' character? So when the user makes the first click on the keyboard, the fetch will run twice (Once with an empty string and other run with the 'F' char ). Please if I'm wrong correct me, and thanks again😄.

    • @dealloc
      @dealloc Před rokem

      No it only runs the first closure (i.e. previous closure) with the empty string, because only a single event happened :)
      The previous closure is always around until it has finished executing, including Promises that are scheduled. Then it will be discarded (garbage collected) later. However, this is handled by the JavaScript engine and is not something you can change.

  • @abderrahmandouara9973

    Any books suggestions to learn backend development with NodeJS

  • @harshilparmar9076
    @harshilparmar9076 Před rokem

    Hey Jack, It was really awesome !! only one doubt 13:46 you are saying that old value of dependency array is undefined and new value will be empty string. But I am thinking we are setting empty string as initial value so it should be empty string dependency array right? Could you please correct me where I am missing?

    • @jherr
      @jherr  Před rokem +1

      TBH, I'm not sure what React is comparing the dependency array with the first time through, could be undefined, or they might not be comparing it at all since they see they have no previous dependency array to look at. The net effect is, all registered effects are run one, and then their dependency array values at that first registration become the previous values for subsequent effect registrations.

    • @harshilparmar9076
      @harshilparmar9076 Před rokem

      @@jherr Thank you so much 🙌

  • @stanleychukwu7424
    @stanleychukwu7424 Před rokem +1

    First sponsored video 🙌🙌🙌🙌🙌🙌🙌🙌

  • @BuIIetBiII
    @BuIIetBiII Před rokem +4

    I always thought useState was async because of that bug so this helps a lot. The only problem is it involves closures and I've never really properly understood closures in javascript

  • @spiridonov1
    @spiridonov1 Před rokem

    Does the order of setState and useEffect matter? If the use effect is after the handleSetValue closure is there a different effect?

  • @ankanbasu7381
    @ankanbasu7381 Před rokem +1

    will the useEffect run after re-render due to setSearch or will useEffect run first immediately after 'search' is changed and then react will re-render (together for setSearch and setResults) ?

    • @jherr
      @jherr  Před rokem +1

      useEffects never run immediately. They always run after the renders have been completed.

    • @ankanbasu7381
      @ankanbasu7381 Před rokem

      @@jherr ok. i understood. thanks!

  • @sppanday_
    @sppanday_ Před rokem +1

    Hi, I have seen you doing module federation in React web but can you do react module federation for desktop/electron application . Can you do a video showing how can you solve problem of accessing remoteEntry access problem from host app to other apps such as app1 and 2.

    • @jherr
      @jherr  Před rokem

      Sounds really cool, but I'm not seeing a lot of interest that. Like this is the first request I've had for a video like that. Just bein' honest with you. I have had a LOT of requests for Module Federation with NextJS. So I probably will be doing that one soon.

  • @blizzy78
    @blizzy78 Před rokem +2

    8:14 You mention that the only thing that has changed is the value. This is not true: onChange also contains a new function value as well, so the onChange property has changed as well.

    • @jherr
      @jherr  Před rokem

      You are correct. The reference to onChange did change as well. Though technically I'm not sure if that unregisters and re-registers an event handler. Or if the event handler just calls the most recent reference. Either way an event handler update wouldn't force a paint. :)

  • @matthewkim5139
    @matthewkim5139 Před rokem

    Hi Jack,
    Just to make sure I am on the same page,
    The setter function returned from useState is synchronous as it updates the state value in the array associated with the component instance instantly, but the result of re-rendering the page based off the new state is asynchronous?

    • @jherr
      @jherr  Před rokem +1

      Yes, exactly.

  • @BezzantSam
    @BezzantSam Před rokem +1

    Jack you are the best

  • @tonimaunde
    @tonimaunde Před rokem +1

    Gold.

  • @thecutedreamkostasp.4449

    This guy is OP!

  • @Talezus
    @Talezus Před rokem +4

    Something to note with this example that I think should be addressed even if it isn't really in the scope of this video:
    If you're making frequent asynchronous calls based on user input such as with the fetch example you need to be careful that your results do not get mismatched. For example, if a user types "abc" then three asynchronous fetches will be made and it is possible that the response for "ab" is resolved after that of "abc". This means the results the user will see will be from the search "ab" and not "abc".

    • @jherr
      @jherr  Před rokem +2

      Yes, you should definitely debounce this IRL.

    • @zhongtom2625
      @zhongtom2625 Před rokem +1

      I think the useEffect clean up function is to solve that issue, to cancel the previous fetch request.

  • @DarkShadow00972
    @DarkShadow00972 Před rokem +1

    Nice video but how to avoid re render of functions which is inside functional component and why it is happened that way pls answer, Thanx

    • @jherr
      @jherr  Před rokem +1

      The whole point of the video is that you shouldn't be creating component definitions in your parent component in the first place. So the answer is to remove them.
      And if you are creating render function in your components then pull that code out of your component by turning those functions into real components. And perhaps use `memo` if avoiding re-renders is such a big deal to you.

    • @DarkShadow00972
      @DarkShadow00972 Před rokem

      @@jherr thanx 👍

  • @a89529294
    @a89529294 Před měsícem

    At 13:50, you mentioned that the previous value of search is undefined, so that is why the effect runs. Does this mean if you set the initial value of search to be undefined, the effect will not run on mount?

    • @jherr
      @jherr  Před měsícem

      Yeah, I was wrong when I said that. It's not set to undefined. I don't actually know what it's set to, but the behavior is, if you pass undefined then the effect/callback/memo will always run, if you set it to an empty array it will run only once. And then if you set it to an array of values then those values are checked using `Object.is`. This is something you can, and should, try on your own to make sure that you understand the behavior. It's a pretty simple test involving some kind of state changer (a counter) and a console log.

  • @ShaharHarshuv
    @ShaharHarshuv Před rokem +1

    You mention that the setState function is "marking the state is dirty". Are you implying that the re-render does not happen immediately? I was under the impression it is.
    For example, if I have two consecutive "setState" function calls, will it re-render twice, or just once?

    • @jherr
      @jherr  Před rokem +1

      Once. Try it.

  • @harmmeijer6582
    @harmmeijer6582 Před rokem

    The search value in the event handler function is a stale closure, there are plenty of articles about stale closures in React.
    There is still a common bug in your code though and that is setting search result without checking if that result is the result of the current value of search. For example: the user types "abc" then 3 async calls are made: "a", "ab" and "abc" but the order in which they resolve is not guaranteed, lets say "a" takes 2 seconds and the other 2 take 100ms then "ab" and "abc" will resolve and set result and after almost 2 seconds "a" will resolve and set result. Now your UI will display you are searching for "abc" and the results show the search result for "a".
    Debounce will not guarantee a solution to this, the only way to guarantee it is to either cancel a previous fetch when search changes or check on resolve if search changed during the fetch if it changed you can resolve with a special cancel value and not set the UI with this value.

    • @glowiever
      @glowiever Před rokem

      debounce seems to work just fine. the debounced function delayed until the set time has passed. in which it's final. as long as it's according to user's expectation it should be fine.

    • @harmmeijer6582
      @harmmeijer6582 Před rokem

      @@glowiever Denounce does not guarantee correct behavior bit makes the bug less likely to occur. Slow responses could still cause several active requests that do not resolve in the same order they have been made.

    • @glowiever
      @glowiever Před rokem

      @@harmmeijer6582 just disable input while waiting for response. easy

    • @harmmeijer6582
      @harmmeijer6582 Před rokem

      @@glowiever That is also an option but a very bad user experience to "lock" the ui while doing async.

  • @jjscale
    @jjscale Před rokem

    Hey, very nice video, I have a somehow related question. I have a variable in my app let's call it "isAuthenticated" I set the initial state as false and then I try to initialise it with useEffect an api call on the server. Somehow when the app is running the variable is always false( the initial value), even though I can console.log inside the useEffect and see that the state is changing over there. Does anybody have a clue on what is happening ? Thank you

    • @jherr
      @jherr  Před rokem +1

      There is a Discord server associated with the channel. Feel free to post your question there, but please read and follow the #rules first. They will help you in constructing a question that will get you the answer you need. discord.gg/eJ5bYFb6

    • @BlackHawkkDown
      @BlackHawkkDown Před rokem

      Sounds like you ain't setting the changed data to the isAuth
      for example:
      const [isAuth, setIsAuth ] = useState("false");
      useEffect(() => {
      const getAuth = async () => {
      const response = await fetch(`/API/GETAuth/${user}`)
      const data = await response.json();
      setIsAuth(data);
      };
      getAuth();
      }, [user]);

  • @user-td1qf7rg6q
    @user-td1qf7rg6q Před rokem

    A quick question here Jack or rather a confirmation, approach one where we have not used a useEffect is going render one time lesser than when we have used useEffect while achieving the same feat right?

    • @jherr
      @jherr  Před rokem

      I don't follow. Can you give me a time reference or something so that I can catch up with where you are looking at least?

    • @user-td1qf7rg6q
      @user-td1qf7rg6q Před rokem

      @@jherr Yes sure so up until 12:30 or so where we've not introduced a useEffect vs after are the two cases I am talking about

    • @jherr
      @jherr  Před rokem

      @@user-td1qf7rg6q Ok, yes, it will render one less time. That being said, I wouldn't worry about extra renders. Your React components generate VDOM elements, which means they don't "re-draw the page" every time they are re-rendered. If the content doesn't change then nothing is changed on the page. So you don't need to sweat the extra re-render here or there.

  • @aadil4236
    @aadil4236 Před rokem

    But if we set the search with the setSearch function before the fetch. wouldn't the search should be updated with the new value? still a bit confused.

    • @jherr
      @jherr  Před rokem +1

      No, because search is just a local scalar which points to the original value of the search field from the previous render.

    • @aadil4236
      @aadil4236 Před rokem

      @@jherr I rewind the video infinite times to understand. And finally! I got it. The closure is the culprit here. I still have a question, I get it that numbers and strings are passed and returned by values. But, what if I'm updating an array or an object? when I update the array or object with setState's set function shouldn't it update that same array or object because it's just a reference?

  • @hiepnguyen-jo3dc
    @hiepnguyen-jo3dc Před rokem

    Hi Jack, please explain why call setState directly at top level in a function component (not nested in any event-handler function) will cause infinite loop? Thank you so much!

    • @antonpogonii8413
      @antonpogonii8413 Před rokem

      state change causes component to render, therefore setting unconditioned setState will cause state change, which will cause a setState to run again and so on in the loop

    • @bnodonprojukt2124
      @bnodonprojukt2124 Před 6 měsíci

      @@antonpogonii8413 but if i use setState(1) at the top of my functional component, why does it causes infinite loop. updating with same value doesn't causes re-render if it's inside a event handler

  • @user-ww3gl7kx6u
    @user-ww3gl7kx6u Před 7 měsíci

    @9:18
    where can i read more about this?

    • @jherr
      @jherr  Před 7 měsíci

      If it's about then(setData). Think of it like this:
      [1,2,3].map(x => x + 10);
      Is the same as:
      const add10 = v => v +10;
      [1,2,3].map(add10);
      Which is the same as:
      const add10 = v => v +10;
      [1,2,3].map((v) => add10(v));
      So:
      then((d) => setData(d));
      Is the same as doing:
      then(setData);
      Except that you are adding an additional function call. This isn't "documented" anywhere, it's just the nature of the JavaScript language (and other languages too.)

  • @alisherwhite4616
    @alisherwhite4616 Před rokem

    will conference be streamed on this channel October 25th ?

    • @jherr
      @jherr  Před rokem +1

      One track from the first day

  • @wizardtechnical
    @wizardtechnical Před rokem

    When a user does not enter any thing after f, then why it's fetching again?

  • @vakhtangnodadze4802
    @vakhtangnodadze4802 Před rokem +1

    Can anyone please explain 10:45 a bit in depth? I don't understand, if useState is NOT asynchronous, meaning it updates the search instantly, shouldn't the fetch have information about the most updated search value, in this case, 'f'?
    What exactly do you mean "you are not updating that local copy"? What difference does it make that it's just a string?
    The way I see is this and please tell me if I'm wrong.
    1)User clicks on input and enters a string, let's say "f"
    2)setSearch sets that value ("f") to the useState search and is this where the problem arises?
    3)Before React could re-render to register the change, the fetch command is run anyways with the old value?
    4)We do not go to the return function
    5)Component is updated after re-render, the values are updated now with the search useState value being "f" instead of empty string.
    6)The fetch had already run with the old value, it fetches with that old value(meaning the empty string)
    7)The fetch returns the data, we update the results useState and the component re-renders again
    So in the end, we have incorrect data, because the state is kind of "one step behind".
    Could you please tell me if I understood the process correctly and also answer my weird questions.
    Thank you Jack for this video! Keep up the great work!

    • @jherr
      @jherr  Před rokem +1

      The steps you laid out here are exactly correct. The problem comes from saying "setSearch updates "search"". setSearch sets the value of the "search slot" in the data associated with this instance of the component. It does NOT end up changing the value of the local search variable since that was set at the moment you got it from useState when the function started.
      If you are familiar with databases or microservices think of it like that. Calling useState gets the current value from the microservice (or DB) and gives that to you, plus a setting function. You then call that setting function which updates the microservice. But you still have the local copy of the data that you got when you first called. You would need to call the microservice to get another copy of the new value, right? In React, you don't need to do that because you will get called again and get the new value. But that won't happen until after you invoke the fetch with the old value.

  • @leodevbro
    @leodevbro Před rokem +1

    2:13 - I think there is a mistake in the code. "event . target" does not have "currentValue". TypeScript would show an error like this: " " " "Property 'currentValue' does not exist on type 'EventTarget & HTMLInputElement'. [ts(2339)] " " " "

    • @jherr
      @jherr  Před rokem +1

      Fair enough my bad.

    • @zero_cool
      @zero_cool Před rokem +1

      It should be either evt.currentTarget.value or evt.target.value.