UseState: Asynchronous or what?

Поделиться
HTML-код
  • Опубликовано: 10 июл 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
  • НаукаНаука

Комментарии • 268

  • @pim8268
    @pim8268 Год назад +116

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

  • @jherr
    @jherr  Год назад +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 Год назад

      Great Explanation Jack🙌

    • @dhavall08
      @dhavall08 Год назад

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

    • @jonisapp
      @jonisapp Год назад +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 Год назад

      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  Год назад +1

      @@dhavall08 Force of habit.

  • @tthiagolino8
    @tthiagolino8 Год назад +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  Год назад +15

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

    • @bastek338
      @bastek338 Год назад +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  Год назад +5

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

    • @DisturbedNeo
      @DisturbedNeo 11 месяцев назад

      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.

  • @13zebras
    @13zebras Год назад +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 Год назад +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 Год назад

    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!

  • @jjrise
    @jjrise Год назад +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!

  • @user-ku2sn1wz1c
    @user-ku2sn1wz1c Год назад +1

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

  • @vatsalyasinghi438
    @vatsalyasinghi438 Год назад +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 !

  • @pupfriend
    @pupfriend Год назад +1

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

  • @wunshon
    @wunshon Год назад +2

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

  • @tayloratheo
    @tayloratheo Год назад +2

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

  • @hameedpilot
    @hameedpilot Год назад +1

    Lovely and informative one... Thanks sir!!

  • @eminm6383
    @eminm6383 Год назад

    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.

  • @mrjebbar
    @mrjebbar Год назад +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  Год назад +1

      Thank you so much! Happy to have your sub!

  • @ofirlevy3682
    @ofirlevy3682 Год назад +1

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

  • @elhaambasheerch7058
    @elhaambasheerch7058 6 месяцев назад

    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!

  • @_hugo_cruz
    @_hugo_cruz Год назад +1

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

  • @Gangbuster74
    @Gangbuster74 Год назад +1

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

  • @dieteroberkofler4342
    @dieteroberkofler4342 Год назад +1

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

  • @shashikantmarskole
    @shashikantmarskole Год назад +1

    thank you Jack , nicely explain it...

  • @KresimirKatusic
    @KresimirKatusic Год назад +1

    Excellent teacher, great video, thank you

  • @gendash
    @gendash Год назад

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

  • @abdullahrafique2883
    @abdullahrafique2883 Год назад +1

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

  • @0xVantwoutMaarten
    @0xVantwoutMaarten 8 месяцев назад

    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.

  • @SumitKumar-tw4qe
    @SumitKumar-tw4qe Год назад +5

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

    • @alain_laroche
      @alain_laroche Год назад +1

      🤣Was about to comment the same thing 🤣

  • @criticalthinker88gis13
    @criticalthinker88gis13 Год назад +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.

  • @michaelrooze278
    @michaelrooze278 Год назад +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 Год назад +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  Год назад +1

      The squirrels are very cheeky.

  • @Bbehemothh
    @Bbehemothh Год назад +1

    So glad that youtube recommended this!

  • @matheussunderhus9421
    @matheussunderhus9421 Год назад +1

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

  • @emilito4
    @emilito4 Год назад +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).

  • @jampy42
    @jampy42 Год назад

    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!

  • @hangtran4863
    @hangtran4863 Год назад +1

    i love your background so much, beautiful nature

  • @fmictsang8874
    @fmictsang8874 Год назад +1

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

  • @DjLeonSKennedy
    @DjLeonSKennedy Год назад +1

    No one could explain better, thanks!

  • @serjio8781
    @serjio8781 Год назад +1

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

  • @walterlol
    @walterlol Год назад +3

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

  • @randomforest_dev
    @randomforest_dev Год назад +1

    good explanation!

  • @allaithbitar1199
    @allaithbitar1199 Год назад +1

    Holy knowledge 🔥
    God bless your effort 🖤🔥

  • @b0tm0de
    @b0tm0de Год назад +1

    Thank you.

  • @mutantgaming8331
    @mutantgaming8331 Год назад

    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. 😃

  • @MohamedNasser1
    @MohamedNasser1 Год назад +1

    Thanks! You're the greatest

  • @VikasTalksTech
    @VikasTalksTech 22 дня назад

    where can i know more the control flow in js

  • @djaalabahmed2038
    @djaalabahmed2038 Год назад +2

    Great Jack 👌👌

  • @H4KnSL4K
    @H4KnSL4K Год назад +1

    Thanks!

  • @AsakuraAvan
    @AsakuraAvan Год назад

    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?

  • @aseemanand1
    @aseemanand1 Год назад

    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.

  • @karangill2065
    @karangill2065 Год назад +1

    I'm Amazed!

  • @bythealphabet
    @bythealphabet Год назад +1

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

  • @Johnny-rn8fb
    @Johnny-rn8fb Год назад +1

    another awesome video

  • @abderrahmandouara9973
    @abderrahmandouara9973 Год назад

    Any books suggestions to learn backend development with NodeJS

  • @kmylodarkstar2253
    @kmylodarkstar2253 Год назад

    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  Год назад +1

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

  • @florianbopp187
    @florianbopp187 6 месяцев назад

    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.

  • @mrSargi7
    @mrSargi7 Год назад +1

    Best React channel in the whole youtube!

  • @robertminardi4268
    @robertminardi4268 Год назад +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  Год назад +1

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

  • @emreozgun3846
    @emreozgun3846 Год назад +2

    this guy is a fucking wizard.

  • @WomboBraker
    @WomboBraker Год назад +1

    thank you

  • @ebrelus7687
    @ebrelus7687 Год назад +1

    proper tempo for learning 👌

  • @a89529294
    @a89529294 26 дней назад

    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  26 дней назад

      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.

  • @matthewkim5139
    @matthewkim5139 Год назад

    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  Год назад +1

      Yes, exactly.

  • @amans6504
    @amans6504 Год назад +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

  • @ThienNguyen-do4eo
    @ThienNguyen-do4eo Год назад +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 😂

  • @wizardtechnical
    @wizardtechnical Год назад

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

  • @ShaharHarshuv
    @ShaharHarshuv Год назад +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  Год назад +1

      Once. Try it.

  • @masterj1081
    @masterj1081 Год назад +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  Год назад +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 Год назад +1

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

    • @nimeshvaghasiya1663
      @nimeshvaghasiya1663 Год назад

      @Master J @Jack Herrington currently, I have used to useExternalStore from ruclips.net/video/4MmmlWwlST4/видео.html by jack to have global state management.

  • @ankanbasu7381
    @ankanbasu7381 Год назад +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  Год назад +1

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

    • @ankanbasu7381
      @ankanbasu7381 Год назад

      @@jherr ok. i understood. thanks!

  • @DisturbedNeo
    @DisturbedNeo 11 месяцев назад

    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"

  • @luiscode92
    @luiscode92 Год назад +1

    wowww, thanks

  • @ahmedawji846
    @ahmedawji846 Год назад

    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 Год назад

      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.

  • @DarkShadow00972
    @DarkShadow00972 Год назад +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  Год назад +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 Год назад

      @@jherr thanx 👍

  • @krumbo
    @krumbo Год назад +1

    Wow good stuff, where have been before?

  • @matttamal8332
    @matttamal8332 Год назад +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  Год назад +2

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

    • @matttamal8332
      @matttamal8332 Год назад

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

    • @jherr
      @jherr  Год назад +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 Год назад

      @@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.

  • @user-ww3gl7kx6u
    @user-ww3gl7kx6u 6 месяцев назад

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

    • @jherr
      @jherr  6 месяцев назад

      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.)

  • @smash3689
    @smash3689 Год назад +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  Год назад +1

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

    • @smash3689
      @smash3689 Год назад

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

  • @amanali9501
    @amanali9501 Год назад

    Plz make a video on sequence of multiple useEffect

  • @spiridonov1
    @spiridonov1 Год назад

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

    • @jherr
      @jherr  Год назад

      None at all.

  • @jjscale
    @jjscale Год назад

    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  Год назад +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 Год назад

      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]);

  • @RamaKrishna-hh7cx
    @RamaKrishna-hh7cx Год назад +1

    9:15 - what exactly is happening here, can you please explain. As I understand, setState() is a function and you need to pass a new value to it so it can update the state. when you type `.then(setState)`, what exactly is the meaning? I don't even understand the syntax there, how does the setState function gets the data it needs?

    • @jherr
      @jherr  Год назад +1

      setState is a function, so you can pass it to the `then` function as the parameter. And then then will invoke it just as it would a function that you specify within the then.
      `.then(setState)` gives you exactly the same result as `.then(data => setState(data))`
      The difference is that you are just adding an unnecessary step in there by adding a new function in the middle between `then` and `setState`.

  • @mihaimanole2643
    @mihaimanole2643 Год назад +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  Год назад

      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 Год назад

      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.

  • @hiepnguyen-jo3dc
    @hiepnguyen-jo3dc Год назад

    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 Год назад

      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 5 месяцев назад

      @@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

  • @vakhtangnodadze4802
    @vakhtangnodadze4802 Год назад +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  Год назад +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.

  • @aadil4236
    @aadil4236 Год назад

    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  Год назад +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 Год назад

      @@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?

  • @alisherwhite4616
    @alisherwhite4616 Год назад

    will conference be streamed on this channel October 25th ?

    • @jherr
      @jherr  Год назад +1

      One track from the first day

  • @rorycawley8334
    @rorycawley8334 Год назад +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.

  • @BezzantSam
    @BezzantSam Год назад +1

    Congrats on the sponsor

  • @osirri
    @osirri Год назад +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 Год назад +1

      saw that someone else commented this already. ignore

  • @user-td1qf7rg6q
    @user-td1qf7rg6q Год назад

    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  Год назад

      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 Год назад

      @@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  Год назад

      @@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.

  • @sppanday_
    @sppanday_ Год назад +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  Год назад

      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.

  • @harshilparmar9076
    @harshilparmar9076 Год назад

    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  Год назад +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 Год назад

      @@jherr Thank you so much 🙌

  • @robertrocha7216
    @robertrocha7216 Год назад +1

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

    • @jherr
      @jherr  Год назад +1

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

  • @BezzantSam
    @BezzantSam Год назад +1

    Jack you are the best

  • @alisherwhite4616
    @alisherwhite4616 Год назад

    Hey! There is something i am not able to understand, here I see initial value being logged to console but i dont have any closure happening here (code crashes with too many re-renders errors but thats not the point :) ). Can someone explain what is going on in the code below ?
    import React from "react";
    const App = () => {
    const [state, setState] = React.useState(0);
    setState(1);
    console.log(state);
    return i am app;
    };

    • @jherr
      @jherr  Год назад

      You have an infinite loop there.

    • @jherr
      @jherr  Год назад

      Actually it shouldn’t be an infinite loop because after you set state to 1 subsequent setStates to 1 should be ignored.
      The console.log showing the original zero value is because you have a copy of the value of state at when it started at the beginning of this function so 0. And there is NO dynamic connection between the number stored in the state associated with the component instance and this copy of it. So your local copy will not change when you do setState.

    • @alisherwhite4616
      @alisherwhite4616 Год назад

      @@jherr got it, thank you

  • @harmmeijer6582
    @harmmeijer6582 Год назад

    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 Год назад

      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 Год назад

      @@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 Год назад

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

    • @harmmeijer6582
      @harmmeijer6582 Год назад

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

  • @thecutedreamkostasp.4449
    @thecutedreamkostasp.4449 Год назад +1

    This guy is OP!

  • @ShaharHarshuv
    @ShaharHarshuv Год назад

    You still have a boomerang effect though as the onChange event causes a change in the value attribute. I think this is generally not a recommended practice. How would you avoid that?

    • @jherr
      @jherr  Год назад

      Can you give a time reference?

    • @ShaharHarshuv
      @ShaharHarshuv Год назад

      @@jherr I mean in the end code - the input's value attrbute will (unnecessarily) change upon user input. Think this is generally not recommended ("boomerang effect"). I don't think it causes any bug so it might be fine

    • @jherr
      @jherr  Год назад

      @@ShaharHarshuv Yeah, you should definitely call the fetch from inside the event handler, and probably on a debounce.

  • @leodevbro
    @leodevbro Год назад +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  Год назад +1

      Fair enough my bad.

    • @zero_cool
      @zero_cool Год назад +1

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

  • @Talezus
    @Talezus Год назад +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  Год назад +2

      Yes, you should definitely debounce this IRL.

    • @zhongtom2625
      @zhongtom2625 Год назад +1

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

  • @tonimaunde
    @tonimaunde Год назад +1

    Gold.

  • @deadvalentine1000
    @deadvalentine1000 Год назад +2

    whats that thing in the background?

    • @jherr
      @jherr  Год назад +1

      The squirrel?

    • @jovanmilosevic8336
      @jovanmilosevic8336 Год назад

      @@jherr Right! It's the squirrel going at the feeder. At the very beginning around 0:38. I had to find out.