Search code examples
javascriptreactjsjsxjavascript-objectsreact-state

State not updating on the first onClick events


im new to react and I came into a problem I cannot seem to fix, Im trying to reacreate the iPhones notes app and theres this issue that when I first hit + to add a new note it doesnt get added into the state array, whats weird is that it works normally the second time I click it and so on

screenshot for the array problem

My 2nd issue is that theres this "activeObj" state variable which stores the clicked notes object but also normally works on the 3rd try, the first and second clicks look like this (check screenshots)

screenshot for the activeObj problem

I tried changing the syntax and the structure of the functions but my skills are still limited since its my first week of doing react


Solution

  • When you call the setState method, it updates the state behind the scenes, and then schedules a re-render of your component with the state variable (e.g. arrayOfNotes) set to the new value. Because you've got your console.log inside the function that's calling the setState method, you're logging the old value, because it hasn't done the re-render yet.

    Next render cycle it'll be fine, in fact you could move your console.log into the body of the component and see it'll behave as you're expecting.


    When you're updating a state and the new state value depends on the previous one, I'd also recommend using the function version of setState precisely for this reason, e.g.

     setArrayOfNotes((prev) => [newNoteObject, ...prev])
    

    This is because prev will take into account other sets done this render cycle, but the way you're doing it currently won't. Doing it this way will certainly save you from other bugs later on.


    The cycle order also is what's causing your second issue. You're setting the active note, but because the set won't apply until the next re-render, activeNote will still be the old value in the line below, when you're expecting it to already have been updated. You can just pass id in there instead in this case.