UseState: Asynchronous or what?

แชร์
ฝัง
  • เผยแพร่เมื่อ 30 ก.ค. 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 TH-cam is important for us developers... Thank You Jack!

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

      absolutely

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

      Quality of the person shows in these videos.

  • @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 ปีที่แล้ว

      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.

  • @xc13z829
    @xc13z829 ปีที่แล้ว +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!

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

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

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

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

  • @user-ku2sn1wz1c
    @user-ku2sn1wz1c ปีที่แล้ว +1

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

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

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

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

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

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

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

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

    Lovely and informative one... Thanks sir!!

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

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

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

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

  • @0xVantwoutMaarten
    @0xVantwoutMaarten 9 หลายเดือนก่อน

    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.

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

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

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

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

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

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

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

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

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

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

    thank you Jack , nicely explain it...

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

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

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

    Excellent teacher, great video, thank you

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

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

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

    So glad that youtube recommended this!

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

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

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

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

    good explanation!

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

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

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

    No one could explain better, thanks!

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

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

    Holy knowledge 🔥
    God bless your effort 🖤🔥

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

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

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

    Great Jack 👌👌

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

    Thank you.

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

    Thanks! You're the greatest

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

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

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

    Thanks!

  • @Johnny-rn8fb
    @Johnny-rn8fb ปีที่แล้ว +1

    another awesome video

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

    Wow good stuff, where have been before?

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

    this guy is a fucking wizard.

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

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

    I'm Amazed!

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

    Best React channel in the whole youtube!

  • @VikasTalksTech
    @VikasTalksTech หลายเดือนก่อน

    where can i know more the control flow in js

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

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

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

    Any books suggestions to learn backend development with NodeJS

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

    proper tempo for learning 👌

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

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

  • @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 th-cam.com/video/4MmmlWwlST4/w-d-xo.html by jack to have global state management.

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

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

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

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

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

    thank you

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

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

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

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

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

    Congrats on the sponsor

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

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

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

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

    wowww, thanks

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

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

    Plz make a video on sequence of multiple useEffect

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

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

  • @a89529294
    @a89529294 หลายเดือนก่อน

    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  หลายเดือนก่อน

      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.

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

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

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

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

    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"

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

  • @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 6 หลายเดือนก่อน

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

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

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

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

  • @user-ww3gl7kx6u
    @user-ww3gl7kx6u 7 หลายเดือนก่อน

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

    • @jherr
      @jherr  7 หลายเดือนก่อน

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

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

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

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

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

    will conference be streamed on this channel October 25th ?

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

      One track from the first day

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

    I have a really stupid question about the calls to "setResults". I get that no arrow function is needed in that final "next". It looks to me as though "setResults" needs an argument containing the value for the "results" array. Where does that value come from in the chain that follows the "fetch"? This is probably obvious, but it's a mystery to me at the moment. Is this another of these "convenience" shortcuts that obscure readability in order to save a few characters of code?
    How is the value of "resp.json" passed to the "setResults" state setter in this code example?

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

      in short: it's because .json() returns a promise. Most complete answer: it's because of promise chaining : 1) fetch returns a promise resolving with a Response object. 2) So the first .then() executes the arrow function callback with that http response value as argument. That function returns a promise resolving with the json value of the response body 3) setResults is called with that value. Difficult to be clear when speaking about promises... I hope that my answer is sufficiently comprehensible.

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

      @@jonisapp : I appreciate your clear and comprehensible answer. To paraphrase, it's another of those "convenience" shortcuts that obscure readability in favor of brevity. I don't want to post a guess at a more verbose version, but it sounds as though that call to setResponse could be rewritten to show the argument with no performance penalty.

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

      Absolutely it could be rewritten and, yes, it wouldn't be any real performance benefit. That being said, I do actually think understanding with both `then(setResults)` and `then((data) => setResults(data))` work helps folks understand more about how JavaScript works.
      For example, if you do:
      const onClick = useCallback(() => { ... }, [...]);
      And then do:
      ...
      That's fine. But if you do:
      onClick(evt)}>...
      Which is the "same thing", it actually hurts you because now you are generating a new function reference for that little anonymous function each time you render. As opposed to with the original onClick={onClick} version where you are passing the same function reference over and over again (assuming the dependencies on the useCallback don't change).

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

      @@jherr Indeed. The entire topic of functions, arrow functions, closures, and function promotion is both deep and crucially important. My thought would be to rewrite just the setResults call using the second form simply to remind the developer of what is actually happening. Web-based tutorials are chock full of rubbish examples that use the bogus onClick handler that you offer -- and that do not explain why it misbehaves the way it does. I appreciate your attention.

  • @thecutedreamkostasp.4449
    @thecutedreamkostasp.4449 ปีที่แล้ว +1

    This guy is OP!

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

    Jack you are the best

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

  • @blizzy78
    @blizzy78 ปีที่แล้ว +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  ปีที่แล้ว

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

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

    What is happening with those squirrels in the background?