Every Beginner React Developer Makes This Mistake With State

Поділитися
Вставка
  • Опубліковано 12 вер 2024

КОМЕНТАРІ • 236

  • @cmlttnts4906
    @cmlttnts4906 2 роки тому +367

    I wouldn't call this example a "derived state example". This is two different states having a relationship. Derived state means a value that is directly calculatable from other states. Selected user cannot be calculated from other states (users), it simply requires a user input ( outside event). This is still a good example of "states with relationship, should be updated together" example.

    • @PavanMehta
      @PavanMehta 2 роки тому +10

      I agree with you.

    • @robertsandiford6223
      @robertsandiford6223 2 роки тому +49

      It's essentially the data normalisation problem from relational databases. Don't store the same data in 2 places or risk inconsistencies. Instead store a reference to a single location.

    • @cmlttnts4906
      @cmlttnts4906 2 роки тому +27

      @@robertsandiford6223 Yes. But in database layer, there is a guarantee of unique ID. For frontend, you don't always have that.
      Assume that "id" doesn't exist, or every field can change. For example, next to the "Increment" button, we have a text input, which changes the "id". Now, we have the same initial bug.
      The ultimate solution is to update them both at the event handler ( or use something with reducer, which does the necessary updates in one place through an action).
      I would give a "derived state" example like this. Assume there are 2 inputs, one is "firstName", the other one is "secondName".
      And you hold the "fullName" in state. "fullName" is fully derivable from "firstName" and "secondName". It doesn't need to be stored as state. It should just be calculated whereever you need.

    • @mrhenry60412
      @mrhenry60412 2 роки тому +1

      @@cmlttnts4906 Thanks for your sharing . That’s really helpful and clear.

    • @robertsandiford6223
      @robertsandiford6223 2 роки тому +2

      @@cmlttnts4906 IDs are not guaranteed in databases, it's a design choice to add them. Generally you can choose to ID your state data if you want to.
      You can do parallel updates in event handlers, and that is fine for simple tasks. It's not recommended in large DBs because of the risk of making a mistake - in a simple component it would be ok, but might cause trouble if complexity grows.
      You example with first name and last name matches database normalisation principles - the fields are the single store and value, and they are referenced to build to composite value when required, the same as selecting from multiple tables in relational databases.

  • @yanhuan1
    @yanhuan1 2 роки тому +17

    I think derived state doesn't need to use the useState at all, it should be calculated based on users state.
    So I'm not sure is this a truely example of derived state.

  • @jinggong4033
    @jinggong4033 2 роки тому +2

    my app works just fine coz I put the selectedID in the dependency array of the useEffect where I fetch API and set the state.... but now I see how silly my solution is while I can just use your simple one line of code to define selected state.....changed it immediately! thank you!!!

  • @wallghing
    @wallghing 2 роки тому +13

    You actually "break" the reference to that object when you do return { ...user, etc }, this creates a new object with the same contents, therefore: new reference. You should apply the increment directly to user and return user to keep it working straight.
    But if you work with references you open up to a lot of problems if you dont really comprehend how references work. Unless you dominate or are trying to dominate references, use native values to avoid issues.

    • @HobaiRiku
      @HobaiRiku 2 роки тому

      indeed

    • @uriniumintestor7302
      @uriniumintestor7302 2 роки тому

      Yeah mutating the original user object would be the best fix here

    • @zsoltoroszlany7172
      @zsoltoroszlany7172 2 роки тому +1

      I'm not a React expert yet it caught my eyes too, it was strange but I told myself I just made up. Nevertheless I guess I my intuition was right.

    • @marios594
      @marios594 2 роки тому +2

      what are you talking about? You cant mutate states

    • @HobaiRiku
      @HobaiRiku 2 роки тому

      @@marios594 I think he can, mutating value directly of the item in the array does the same thing, but in React.StrictMode, state updater will run twice. we can get rid of strict mode or use state value (directly from users and set it like [ ...users ]) instead of state updater. still, I'm not familiar with react and I don't know if this is the appropriate way.

  • @Undef1Gned
    @Undef1Gned 2 роки тому +45

    If you have a list of items that doesn't change as often, you could simply save the index of the item in your array. So you don't have to loop through the array to find the correct item

    • @black_platypus
      @black_platypus 2 роки тому

      Yes, the structure here isn't optimal in general. With the IDs, which should be unique, simply being a property within the objects within an array, as opposed to being the indices or keys in an array or object, we're also missing out on directly addressing them.
      I wonder if that's common practice if you're just pulling objects from your DB?

    • @fabienbroquard7690
      @fabienbroquard7690 2 роки тому +2

      Even if the array changes often.. Just using a setSelectedIndex in his selectUser, that's where the find has to be done (as findIndex()), once only when the id changes.. And set to 0 when the usersArray changes to not have a wrong index (or again find the id in the new array). This saves the overhead of useMemo too ;)

    • @esemelekete1330
      @esemelekete1330 2 роки тому +1

      I agree. Accesing a map/array element with index is absolutely quicker than looping through a list of element.

  • @krishgarg2806
    @krishgarg2806 2 роки тому +12

    Thanks. This is a pretty common but annoying possible bug. This is another reason why I love svelte so much, just use $: and it becomes reactive, derived or whatever you want.

  • @baileysli6235
    @baileysli6235 2 роки тому +3

    3:02 - Try to press `F2` for renaming const in whole document. It really helpful sometimes.

    • @ujjvalw2684
      @ujjvalw2684 2 роки тому

      These small tips come from experience. I don't have any 😭

  • @karansamra
    @karansamra 2 роки тому +3

    Why did you pass reference type variable as a dependency to use Memo
    It will change on every render and useMemo will just become inefficient

  • @doc8527
    @doc8527 2 роки тому +8

    Just copy my reply to comment so new devs might be aware of. There are few problems with the video example and solution.
    For the example itself, check the top comments with highest vote regarding the definition of derived state.
    I want to point out the problems with that solutions from some of the comments and the video, the video example is really tricky.
    First, some of comments say use array index so you don't need to use array.find(), it's questionable/wrong to use array index id as selectedUserId cuz the array index will cause bug once the array size changed hence index is not longer unique. If u pretty sure the size and position are static under any circumstances. This approach is probably the most performant and simplest solution
    Second, use the unique user id as the find id. This is the video solution, it's good but when the size is large, it will cause performance issue as the video claimed later.
    However, the useMemo() in this case, doesn't solve the performance issue because when you update the selection, it will modify the array hence cause useMemo() to rerun. the useMemo will be useful only when the parent container is changed but at the same time you don't want to re-render the current selection list. But for this example with its context, the useMemo() solution is simply wrong. the trouble array.find() will still run regarless.
    So what's my answer?
    I would say if the list is large, the performance is important, the initial code is fine.
    You just need to update both selectedUser & users when you call the update, and only update selectedUser if the user id is matching the updated user in users list. You don't even need to use the array.find() and useMemo() in the first place, it also reduces the mental overhead of using memo hooks.
    The root issue of his solution is because the "issue" example he provided doesn't match the definition of derived state. It just looks like it, that's why I called it tricky.
    If the example is derived state, you shouldn't need useMemo() most likely.

  • @user-uw5dv5el8m
    @user-uw5dv5el8m Рік тому +1

    Great video, very helpful !!

  • @akrembc7951
    @akrembc7951 2 роки тому +18

    what he didn't explain is WHY "selectedUser" and the user that its age is incremented are not the same reference?
    the reason is that when incrementing one user's age we mutate that user it by destructuring .. so we're basically creating a new one : return { ...user, age: user.age + 1 }

    • @alecodes
      @alecodes 2 роки тому +2

      It's because the user's state is copied into selectedUser, so they have nothing to do with each other

    • @ricardoamendoeira3800
      @ricardoamendoeira3800 2 роки тому +1

      Thanks, I was wondering why he didn't address that. Sharing the reference would be a simple fix, although it also has its own downsides.

    • @uriniumintestor7302
      @uriniumintestor7302 2 роки тому +5

      @@alecodes no, it’s not copied. SelectedUser references the same exact object which exists in the array of users. The problem is in Increment function, where he replaces the object in the array with a new object. If he just mutated the original object on age increment, everything would work fine, and I’d actually like this solution more.

    • @feritperliare2890
      @feritperliare2890 2 роки тому

      @@uriniumintestor7302 ah but you can't mutate it like that in react cause react is written by crazy people

    • @uriniumintestor7302
      @uriniumintestor7302 2 роки тому

      @@feritperliare2890 I don’t see why not. They use “setState” to set the result state again. Why do you think it wouldn’t work?

  • @mohamadmohamad4242
    @mohamadmohamad4242 2 роки тому +18

    well, good solution but this solution as you said had bad performance since you need to loop in the users' array to find the selected user, 1)alternative solution is to store the users in an object instead of an array like this:
    const [users, setUsers] = useState({
    1: {
    name: "keyle",
    age: 27,
    },
    2: {
    name: "sally",
    age: 30,
    },
    3: {
    name: "mike",
    age: 25,
    },
    });
    and now the selected state can be any id (1,2,3) and you can access the selected user object with o(1)
    and you can make an array of users id to keep track of their sequence like this:
    const sequence = [2 , 1 , 3]
    2)another solution is to keep the users state an array of obj like you did but instead of saving the user id in the selected state, we can just save it is index (since the order does not change)
    thank you for the video amazing

    • @LoryKa
      @LoryKa 2 роки тому +1

      awesome way of thinking. i have to master this way of thinking because usually i have to deal with performance issues in my apps.

    • @sevenstars0711
      @sevenstars0711 2 роки тому +3

      Looping over the array every time the component re-renders is bad, but by using useMemo you get rid of this problem, and you only loop when you need to. There's no need to fundamentally change your code by using objects or some other ways

    • @mrhenry60412
      @mrhenry60412 2 роки тому +1

      what if we just add a state in users like this:
      const [users, setUsers] = useState([
      {
      id: 1,
      name: "keyle",
      age: 27,
      isSelected: false,
      },
      {
      id: 2,
      name: "sally",
      age: 30,
      isSelected: false,
      },
      {
      id: 3,
      name: "mike",
      age: 25,
      isSelected: true,
      },
      ]);

    • @GuthixCss
      @GuthixCss 2 роки тому +4

      @@mrhenry60412 Then we´d still have to loop through the users to find the one that is selected. It would also add complexity since we´d have to unselect one user when the next one is selected.

    • @mrhenry60412
      @mrhenry60412 2 роки тому

      @@GuthixCss well, I just don't think that creating a hook to store id is necessary, when you can manage all user-related info together. What if you need to deal with some functionality like hiding selected user or changing the font color of selected user at the same time?

  • @godwinjohn7564
    @godwinjohn7564 2 роки тому +1

    Thanks so much 🙏 I just removed unnecessary code and increase performance in my project

  • @22afabio
    @22afabio 2 роки тому +4

    Great lesson!
    This is a source of many bugs... I've tried solving it in another way (as a practice).
    My goal was to fix the bug and improve performance, and this is what I came up with.
    export default function UserLop() {
    const [users, setUsers] = useState([
    { id: 1, name: "Kyle", age: 27 },
    { id: 2, name: "Sally", age: 32 },
    { id: 3, name: "Mike", age: 54 },
    { id: 4, name: "Jim", age: 16 },
    ]);
    const [selectedUserIndex, setSelectedUserIndex] = useState();
    function incrementUserAge(id) {
    setUsers((currUsers) => {
    return currUsers.map((user) => {
    if (user.id === id) {
    return { ...user, age: user.age + 1 };
    }
    return user;
    });
    });
    }
    return (


    Select User:{" "}
    {selectedUserIndex == null
    ? "None"
    : `${users[selectedUserIndex].name} is ${users[selectedUserIndex].age} years old`}

    {users.map((user, index) => {
    return (

    {user.name} is {user.age} years old.{" "}
    {
    incrementUserAge(user.id);
    }}
    >
    Happy birthday
    {" "}
    {
    setSelectedUserIndex(index);
    }}
    >
    Select


    );
    })}

    );
    }
    What do you think?

    • @k0si
      @k0si 2 роки тому +5

      this will bug out if you have a dynamic list, as objects under indexes can change

    • @hd33444
      @hd33444 2 роки тому

      @@k0si hey man, would you be able to explain what you mean by that some more??

    • @k0si
      @k0si 2 роки тому +1

      @@hd33444 Well lets say you have 3 item list. So indexes from 0 to 2. Select 2nd item, so index = 1, thats in state now. Now if you would have an option to delete items, you could delete 1st item, and your currently selected item, previously with index == 1, now actually has index == 0 (its the 1st element now). But in your state there would still be, that selected index is index = 1. However, now that would actually be referencing the previously 3rd item in the list. In general using indexes to point to elements in the array is not such a great idea if you have dynamic lists (using .map and its 'index' argument as 'key' prop as well)
      In my experience i found that just having the objects with 'id' key/value and referencing those is the most simple and reliable way to identify them in the list ;)

    • @hd33444
      @hd33444 2 роки тому +1

      @@k0si Ahhh ok yeah that makes sense. Thanks for the answer!

  • @rahulnag9582
    @rahulnag9582 2 роки тому +7

    If we can store the array position in selectedUser state and on update of user in useEffect we can use this array position like user[selectedUser] then it will be far easier and faster compilation of code

    • @kashug.
      @kashug. 2 роки тому

      but also more prune to bugs, to get a negligable performance gain unless you have a wierd case. Usually react does not re-render that often so the linear-search is not done very often and in most cases the list is short enough to not matter anyway. And in those rare cases a useMemo is probably fast enough and less prune to you making bugs.
      (if you store the index you need to be 100% sure the list never changes - and what if we added features for add and delete users later? - you would then have to make sure that you also update the index on those operations. Easy to forget, and would trigger a bug.

  • @Mickey_McD
    @Mickey_McD 2 роки тому +15

    Instead of useMemo maybe put the users in a Map using the ID as the key, or maybe save the array index of the selected user in the state rather than the ID.

    • @ivanche8051
      @ivanche8051 2 роки тому +1

      why not useMemo? That’s what it’s made for

    • @gordonsau2989
      @gordonsau2989 2 роки тому +5

      @@ivanche8051 useMemo can only memorize if the function has already run once. If we select another user that has never been selected, we still have to go through the whole list of users to find the id. Using id as key in this case can search quicker.

  • @kllokoq
    @kllokoq 2 роки тому +1

    Beautiful explanation!

  • @theophilus494
    @theophilus494 2 роки тому

    Awesome 👍... Thanks so much

  • @19JB90
    @19JB90 2 роки тому +5

    Nice Vid. Still happens in my code a lot. Great to have this explained and simplefied :)

  • @poushalibhattacharjee2166
    @poushalibhattacharjee2166 2 роки тому

    Thank you for this tutorial. It helped me understand the concept. Waiting for more such videos on React. A request if you could tutorial on react testing like Jest and React Testing Library

  • @BHFJohnny
    @BHFJohnny 2 роки тому +1

    Yep I like Vue approach more. Computed props are more straightforward there. In React, I do it this way as you showed. useMemos everywhere.

  • @gerasTheMessiah
    @gerasTheMessiah 2 роки тому

    When he uses the "users" array to keep track of changes with the useMemo() call....
    1. What is react checking exactly behind the scenes? Just the pointer to the array "users" or a more deep comparison (things like length, changing the objects (per se or sub-properties) inside each index, etc) ?
    2. Also isn't "users" being re-created on each render cycle? Wouldn't useMemo going to be doing the find() operation every single time?

  • @BarberoPablo
    @BarberoPablo 2 роки тому +1

    Really good explanation and short video, thanks!

  • @koksikskkj7937
    @koksikskkj7937 2 роки тому +1

    Emmm if we know, when the current age is increment, cant we then update current user? incerementAge -> ...changing data in users... -> set current user by inceremening with new date

    • @acabreragnz
      @acabreragnz 2 роки тому +1

      It's dificcult to manage the syncronation, specially when you have lots of states. Keep it simple :)

  • @DanN-no1qk
    @DanN-no1qk 2 роки тому

    Great videos man thanks for all your effort!

  • @lucappelman8558
    @lucappelman8558 2 роки тому +2

    Now I wonder if I ever did this. It seems like a obvious mistake, but of course it can get you in some weird troubles.

  • @huseynfy
    @huseynfy 2 роки тому

    Thanks for another great video!

  • @ElrondMcBong86
    @ElrondMcBong86 2 роки тому

    In all this code/ video there ain't any database-calls / redux used, right?
    I wonder, if/how I can use this, if I have to use database calls.. :-S

  • @chengxiaoxia8046
    @chengxiaoxia8046 2 роки тому +3

    I like Kyle's tutorial course. You explain the concepts clearly and make the courses comprehensive. You share the knowledge, the keys to write simple and high-quality code without reservation. I bought some online React and css courses. I think Kyle's course is worth the price. Thanks.

  • @ioannispotouridis297
    @ioannispotouridis297 2 роки тому

    To go a step further into performance, I'd keep the users state as an object instead, where key is the id and value is the user, so your derived selectedUser state wouldn't have to loop (find) throught the users array every time selectedUserId changed, but actually access it directly e.g. const selectedUser = useMemo(() => users[selectedUserId], [selectedUserId, users]);

    • @Synesthesia-r9
      @Synesthesia-r9 2 роки тому +1

      Seems like a perfect candidate for a Map.

  •  2 роки тому +1

    your useMemo will get re generated every time you click "increment" because you are doing a .map and that's generates a new array so the depenecy array of useMemo will be a new one so your useMemo makes no sense 🙂

  • @samyogdhital
    @samyogdhital 2 роки тому

    amazing video, will definitely keep in mind from next time.

  • @yusufkaraaslan2888
    @yusufkaraaslan2888 2 роки тому

    Thanks !

  • @amitneuhaus2989
    @amitneuhaus2989 2 роки тому +2

    If users list was huge, isn't it inefficient to filter through them? I would suggest saving the users as object with keys as ids, and then getting the selected user is o(1)

    • @arjobansingh1940
      @arjobansingh1940 2 роки тому

      That is also good solution, but then to render users, you have to create array from an Object which would also be O(N) on each render.
      Or again we could useMemo on that object and create new array from that object only when users change.
      But again, we are down to same thing, either we have create array from users object or that filter derived state.
      I guess filter derived state would be faster, as filtering can not always be in worst case, sometimes we can find user ar first place only, and it’s average case would be finding user in mid of an array.
      But on other hand we have to create whole array from Object with Object.keys, values or entries function etc.
      Which is always exactly O(N).

    • @ElektrykFlaaj
      @ElektrykFlaaj 2 роки тому +1

      if the list is huge then the list should get shorter. You can add pagination of some kind

    • @amitneuhaus2989
      @amitneuhaus2989 2 роки тому +1

      Good argument,. you can have list of ids which can represent the order of rendering, and objects of items in object with id as keys.
      Rendering list through the ids array, selecting the object from the objects state.

    • @amitneuhaus2989
      @amitneuhaus2989 2 роки тому

      @@ElektrykFlaaj yeah but when you add pagination and don't have all the data on the UI you lose alot of abilities, like searching on the frontend, and you'll have to do backend search and sort..

    • @arjobansingh1940
      @arjobansingh1940 2 роки тому +1

      @@amitneuhaus2989 yes I guess, depends on use case. If users aren’t going to change much rather selected user would, than using object as initial state in fine, considering we are memoizing the render array with useMemo.
      Otherwise, if users data is getting changed often, we can use this array approach shown in the video.

  • @freshlix9554
    @freshlix9554 2 роки тому

    Very important lesson in your software class.. but who in the interpreted react/js world cares about storage? As far as I know it's always important to keep redundancy low, but it's not always the best tradeoff. At some degree of complexity for a specific calculation you should avoid recalculating specific values time over time, rather than just looking them up in the storage. If your use case isn't time-sensitive as it is the case for most basic applications I usually limit this to a depth of 42 additional operations in comparison to a simple lookup in storage, it's ideomatic just for simplicity and to have this as a reminder if time matters 😅 especially in the SQL area with less 'intelligent' DBMS systems - often found in cluster cases - this helps out to improve the timing overall. Most of the time I would recommend using higher structures represented in arrays or maps/objects to keep track of changes more granularly, but that's case specific, as every decision you make in your life.

    • @freshlix9554
      @freshlix9554 2 роки тому

      But oops, watch out for mutants! 👾

  • @bernardus3289
    @bernardus3289 Рік тому

    Oh wow I thought after a week or 2 of learning react, I got the hang if it but man did I find this video hard to keep track of

  • @iam_ck
    @iam_ck 2 роки тому +1

    I think states having relationship with each other should be treated with useReducer.. as you need an single state but multiple ways to update it...

  • @namanjindal3089
    @namanjindal3089 2 роки тому +1

    Please also share this code, else it gets very difficult to expirement with it

  • @kushagra4401
    @kushagra4401 2 роки тому +2

    Thanks a ton for sharing all this valuable info and experience with us. U are a gem for students like me

  • @benjadiaz6475
    @benjadiaz6475 2 роки тому

    Excellent video, just the explanation I needed. Thank you very much for the video

  • @FreedomForKashmir
    @FreedomForKashmir 2 роки тому

    What's the best to chose among useCallback() and useMemo() ?

  • @timgerk3262
    @timgerk3262 2 роки тому +1

    This is a profound example of by-reference intuition from the real world blowing up on a learning coder. Does Javascript make this any harder, by being subtle about objects vs primitive value ?

    • @black_platypus
      @black_platypus 2 роки тому +1

      Oh, it's an easy trap to fall into for sure. I see "reference types vs value types" and mutation tripping up people all the time. But I wouldn't say objects vs primitives is compounding the issue much. You need to keep track of what you're referencing in any case

  • @tejasnikam3287
    @tejasnikam3287 2 роки тому +1

    Awesome 👍👍

  • @stoncjoesperanto8632
    @stoncjoesperanto8632 2 роки тому

    @Kyle The code is still a little too small to read properly on a phone (tho you have the space in x). Thanks for your videos

  • @romanmed9035
    @romanmed9035 2 роки тому

    useMemo also have a cost. cost of useMemo need compare with cost render.

  • @GuRuGeorge03
    @GuRuGeorge03 2 роки тому +2

    in other words: if u want referential data, u need to store a reference and not the data

    • @kashug.
      @kashug. 2 роки тому

      yeah, the example is more about having copies of data, in those cases you need to make sure you update all the copies. It is not really derived data since you can not derive selectedUser from the state before he added selectedUserId to the state.

  • @narendrareddyyarramreddy2007
    @narendrareddyyarramreddy2007 2 роки тому +3

    useMemo() doesn't have any use in this component because it has both the state variables in the dependency list! So, whatever we do in this component, it'll run the loop through the whole users list to find the selected user

    • @brendon205
      @brendon205 2 роки тому +5

      because it's just an example, in a real application you'll gonna have a lot more states than that

    • @narendrareddyyarramreddy2007
      @narendrareddyyarramreddy2007 2 роки тому

      @@brendon205 yeah makes sense 👍

  • @mikesummer670
    @mikesummer670 2 роки тому +7

    What is the point of useMemo at this case, because if we increment any user age or select new one, there still be .find through list (because there is no other case for rerender), instead we could store key - value object where key is user id and value is user, so we would not need iteration

    • @anniecenter
      @anniecenter 2 роки тому

      This is a very simplified example so that it’s easier for beginners to understand. He mentions in the video that this is useful if you have other state or props making the component rerender, like theme for example.

    • @arjobansingh1940
      @arjobansingh1940 2 роки тому +2

      This is jus an example, Real world app would have lot of other states which could cause render.
      And using object to store data, with userId as key do look okay on surface.
      But it also has same problem.
      Cause React cannot render object, you have to create array of users form users object using Object methods like Object.keys, entries etc on every render which would always he O(N) and than map over that array to show users.
      Basically we are back to same problem, either use state as array of objects and avoid creating array in every re-render ans use filter to find sleeted item.
      Or use object of users with keys being userIds and create array from this object to map over in every re-render

    • @mikesummer670
      @mikesummer670 2 роки тому

      @@anniecenter You if have list with 1000 users and change age to one of them - your array is changing, so it will be .find again through 1000 users even if you did not change selected users and useMemo won't help you with that.

    • @mikesummer670
      @mikesummer670 2 роки тому

      @@arjobansingh1940 You could also store array of IDs, so you will map through array of IDs and get users from key-value storage

    • @arjobansingh1940
      @arjobansingh1940 2 роки тому

      @@mikesummer670 again we are storing two states for one data source.. Exactly the problem this video tried to solve.
      In real world scenarios, we would have feature of adding, deleting users.
      You would have to manage state at both the places with this approach.
      But yeah, dependent on use case, if problem statement is not much complex, storing an array for ids differently could be used

  • @hardwired89
    @hardwired89 2 роки тому

    Thank you for this content 😭😭😭👍

  • @jmg9509
    @jmg9509 2 роки тому

    LMAO I kid you not I was just learning about this in the Scrimba React course. What a coincidink that this would be uploaded only a couple hours prior, and show up as the first thing on my youtube feed.

  • @whizzninja9740
    @whizzninja9740 2 роки тому

    Excellent!

  • @LeonardoHernandezIC
    @LeonardoHernandezIC 2 роки тому

    UseMemo would work only if you are creating a new array each time you update a element ... I there is still a optimization there

  • @divinsmathew
    @divinsmathew 2 роки тому +1

    Why not simply use useEffect to update selected user with users in dependency array?

    • @ElektrykFlaaj
      @ElektrykFlaaj 2 роки тому +2

      because it's not "simply", you're increasing complexity and decreasing readability.
      in general if it's not necessary to store something in state then you probably shouldn't store it in state

    • @andy-ally
      @andy-ally 2 роки тому +1

      useEffect will run after render. It is used for side effects.

    • @ujjvalw2684
      @ujjvalw2684 2 роки тому

      @@andy-ally constructive

  • @andriiauziak1178
    @andriiauziak1178 2 роки тому

    Honestly Kyle, I was going to read the article, I think so...
    So thanks a lot for the video version))

  • @elitracy1784
    @elitracy1784 2 роки тому

    Why not just use the users variable as a dependency in use effect and update selected user in use effect?

  • @jethya3640
    @jethya3640 2 роки тому

    Is your course worth it in 2022 react js?

  • @dave6012
    @dave6012 2 роки тому

    Nicely done. It would be all too easy to try to useEffect to keep state values in sync, and you dodged that pitfall like a baus.

  • @Stubbelur
    @Stubbelur 2 роки тому

    Wouldn't it be more performance to pass users.length into the useMemo dependancy array?

  • @mohithguptakorangi1766
    @mohithguptakorangi1766 2 роки тому

    Can't we use Useref() hook to refer to that selected user?

  • @xice111
    @xice111 2 роки тому

    you can select only id, and pick it by id

  • @blyatMail
    @blyatMail 2 роки тому

    dudeee.. i'm confusseeeddd.. this is too faaasssttt...

  • @AndresGomez-sv7th
    @AndresGomez-sv7th 2 роки тому

    Nice video, but I have a question, if always change user list, useMemo is worth?, because it added a validation to change its value and always values change, I prefer to acces with index but it not always work

  • @tommyjado127
    @tommyjado127 2 роки тому

    Thanks

  • @thecutedreamkostasp.4449
    @thecutedreamkostasp.4449 2 роки тому

    Why dont make an extra selectedUser field in the users state ,and when u update user age u update age of user on users array and the age of selectedUser the same time.

  • @brimmedHat
    @brimmedHat 2 роки тому

    bravo!

  • @shahidshafi1227
    @shahidshafi1227 2 роки тому

    I encountered exact same problem few days ago 😄.

  • @smaranh
    @smaranh 2 роки тому

    Do you have a Redux course?

  • @vitorwindberg4212
    @vitorwindberg4212 2 роки тому +1

    or you can just add a prop to the user you select like selected: true and then you have all your control in only one state :)

    • @andy-ally
      @andy-ally 2 роки тому +2

      You will face another issue in this case. You will need to find currently selected user and set selected to false which in this example is not a big problem, but if you start keeping track of different object states and behaviors inside an object itself it could become a huge pain to update and maintain.

  • @alvin6088
    @alvin6088 2 роки тому

    how about using `useRef`?

  • @caesarbala
    @caesarbala 2 роки тому

    i used useEffect instead of useMemo is there any downside on this approach ?

  • @jeremy_s
    @jeremy_s 2 роки тому

    What's the possible/potential bug here? I don't see any issue with storing the selected user object in state, please provide a concrete example of a potential bug from applying this pattern as opposed to "bad things can happen".

    • @cristianpache5303
      @cristianpache5303 2 роки тому

      He explained it, when he incremented the age of the user on the list, the age of the selected user wasn't changing, because it was stored as a separate state. It is really a bad practice to store the object in a state, because if you do that, you'll have a duplicate state (the user on the list and the same user on the selectedUser state), and you'd have to update both states manually when some attribute of the user changes (in this case, the age)

    • @jeremy_s
      @jeremy_s 2 роки тому

      Yeah glazed over that at 3 in the morning, agreed, thanks!

  • @rohan1765
    @rohan1765 2 роки тому +1

    Can anyone help me to understand,
    After memorizing the function to derive selected user Kyle said that,
    It will help to boost performance if there are bunch of other states - which makes sense,
    But he also said that if we have 1000s of users it will help with performance,
    If users are in dependacy array, meaning that function is going to run and iterate through every user any time user's value change, how would it help here?

    • @mateuszwojciechowski495
      @mateuszwojciechowski495 2 роки тому

      without memoizing, every time you click "increment" the 'selectedUser" function would run each time. With useMemo, only when you click "select" the function will run, thus running only when you need it to, and not whenever the component rerenders

    • @rohan1765
      @rohan1765 2 роки тому

      @@mateuszwojciechowski495 thanks for the reply, isn't users state in the dependacy array, and on increment aren't we updating users state?

    • @joachimfrank4134
      @joachimfrank4134 2 роки тому +1

      Without useMemo the function runs in each rendering of the component, even if no state was changed.

    • @rohan1765
      @rohan1765 2 роки тому

      @@joachimfrank4134 Ohh I get it now, thanks 🙂

  • @awekeningbro1207
    @awekeningbro1207 2 роки тому +9

    2:22, here one way to solve this is: instead of returning a new object in the map, you can do:
    if(user.id === id) {
    user.age += 1;
    }
    return user;
    this will solve this reference inequality issue. However, you should keep this in mind that you are mutating the object.

    • @narendrareddyyarramreddy2007
      @narendrareddyyarramreddy2007 2 роки тому +10

      Mutating the object will lead to a new bug since the component will not re-render as we are returning the old object Reference.

    • @awekeningbro1207
      @awekeningbro1207 2 роки тому +5

      @@narendrareddyyarramreddy2007
      your justification is partially incorrect because that's not how re-render is happening. The array reference is what is being tracked off from state and since .map() returns a new array, this new array and old array is referentially different so react will cause a re-render regardless

    • @narendrareddyyarramreddy2007
      @narendrareddyyarramreddy2007 2 роки тому +2

      @@awekeningbro1207 If I want to return a new object, I would prefer the conventional way of spreading everything and changing required ones.. It looks more cleaner 🤔

    • @arjobansingh1940
      @arjobansingh1940 2 роки тому +1

      @@awekeningbro1207 for this example you are right, array change is causing re-render.
      But consider a case, where each row is a new User component which takes user and renders it’s age and that User component is memoized with memo() HOC as well for performance reasons,
      as there can be tons of rows, and re-rendering every row just so because some parent’s different state is changed or data of some single row is changed, is not feasible.
      Now here, each User component only have user prop, based on its change the User component can re-render.
      But now with your approach, each user object is mutated on age change, thus User component will not re-render, causing old age to render on UI.
      Yeah, you could say that in current case, that is not the problem, but we should write code in a correct way, which can be easily extended.
      Thus we should follow React’s principal of not mutating state.
      Instead of writing React’s code in non-recommended way, and then trying to figure out in future why certain thing is not working on extended features or codebase!

    • @cmlttnts4906
      @cmlttnts4906 2 роки тому +7

      Please don't suggest bad practice, that might be working in this case but mutating state is very bad, you will encounter so many bugs doing that

  • @orlandofury
    @orlandofury 2 роки тому

    Sorry maybe some here asked the same question, how is the name of the extension you are using to show the error in that big modal in the app instead of going to the console??? please a link to it or the name to search it please?

  • @nro337
    @nro337 2 роки тому

    Really great video, valuable to understand. Thanks!

  • @huzbum
    @huzbum Рік тому

    As an angular developer forced into react, it seems to me that react is prone to bugs. You have to get everything right, every time, or you get bugs and/or poor performance.

  • @Matyanson
    @Matyanson 2 роки тому

    What if I use useEffect instead?

  • @abskawser8565
    @abskawser8565 2 роки тому

    What is the Jackson model that?

  • @KathouQC
    @KathouQC 2 роки тому

    Great video, one thing I would say about react hook: I just love it! Before I used to use react use state but once I know how hook work, it's just so much better :)

  • @mrcookie97
    @mrcookie97 2 роки тому

    iirc the beta.reactjs docs talk about this. Basically never store the same data multiple times in state. Only one copy.
    Best solution is selectedUser to be an id or index

  • @lucienchu9649
    @lucienchu9649 2 роки тому

    For me, the tricky part is hunt down the performance issue.

  • @jean-francoisbouzereau6258
    @jean-francoisbouzereau6258 2 роки тому

    This is the "Single Source of Truth" principle

  • @otherstuff1833
    @otherstuff1833 2 роки тому

    updating a state using a callback function is also a solution I guess and no need to use extra hooks,
    so what do you think about that 🤔🤔

  • @jilhenry
    @jilhenry 2 роки тому

    I like his eyes

  • @VanPetersonKpoti
    @VanPetersonKpoti 2 роки тому

    Thanks a lot. it seems simple, but not.

  • @riceymix4688
    @riceymix4688 2 роки тому +2

    Vue: just use computed

  • @ceasardg
    @ceasardg 2 роки тому

    November 4, 2019

  • @malikbhai2285
    @malikbhai2285 2 роки тому

    Dear Bro, me install just react version newly but take some problems,, when i use input tag then page show me only "Blank Page" plz help me....
    i working last 5 days but no any solution...plz make video not show me blank page..me waiting your video. i am from pakistan

  • @IdleAtre
    @IdleAtre 2 роки тому

    when i watch videos like this one, i am glade i chose svelte over react.

  • @christofferhammarstrom
    @christofferhammarstrom 2 роки тому

    Doesn't using useMemo like this reintroduce the bug where the age is not incremented for the selected user?

    • @adarshs4871
      @adarshs4871 2 роки тому

      No , useMemo is just used for optimization it has nothing to do with the logic

    • @christofferhammarstrom
      @christofferhammarstrom 2 роки тому

      @@adarshs4871 I mean the number is still incremented, but because of useMemo it will not be shown as incrementing in the UI.

  • @stepanzavadil
    @stepanzavadil 2 роки тому

    Why not just store the reference?

  • @sameerkumarkalyanshetti3335
    @sameerkumarkalyanshetti3335 2 роки тому

    I'm facing a problem in making website responsive....could u plz help me out?...I will ask my doubt if u replied to this message.....

  • @curtispene3260
    @curtispene3260 2 роки тому

    Why not just make the user array stateful?

  • @shivansharjit7385
    @shivansharjit7385 2 роки тому

    Anyone knows about how to create a javascript sdk ?

  • @yoJuicy
    @yoJuicy 2 роки тому

    is there a way that writing a test would catch this? i dont know tests

    • @reinoob
      @reinoob 2 роки тому

      You can compare the state and the variables during a test, but it isn't a good thing to test, you should test the funcionalities themselves and how the app is behavioring. For instance in this case the test should be that "if i increment a selected user, both lables should show the same information".

  • @keyurgadher6729
    @keyurgadher6729 2 роки тому

    Awesome

  • @thiagohartman5259
    @thiagohartman5259 2 роки тому

    I think using useMemo is overengineering. React developers themselves talk about not doing performance optimizations where there is no bottleneck

  • @pierre1360
    @pierre1360 2 роки тому

    I would store the index not the id

    • @harag9
      @harag9 Рік тому

      Index can change if you inserted a new line of data into the array, the id, should be unique if pulled from a db via an api.

  • @sh0ker
    @sh0ker 2 роки тому

    In short: don't store the same data twice, because then you need to update it twice

  • @nmrd666
    @nmrd666 2 роки тому

    to find the user you can just do:
    users [ id - 1 ]
    for id = 3
    it will go to users[2]

    • @acabreragnz
      @acabreragnz 2 роки тому +1

      You are assuming that there is a relation between the Id and the position in the array. For this simple case is valid, but in general you cannot assume these things (suppose a list of users filtered from the backend)

    • @nmrd666
      @nmrd666 2 роки тому

      @@acabreragnz ye i know youre right