State is a crucial concept in React and therefore it's important to me that you understand how it works.
Use state is how you manage state in functional components and your state can be anything, it doesn't
have to be an array,
it could be some text, a number, an object, an array, a boolean, anything like that.
Use state always returns an array with two elements, no matter what your state is,
if your state is a number, use state still returns an array with exactly two elements because the first element
then always is your latest state snapshot and the second element is a function that allows you to update
that state snapshot. Whenever you update the state snapshot,
React will do two things;
it will update the internally stored state data,
so for example here when we add our first new goal, it will replace the initial state with our brand
new state,
in this case with the brand new array we created with concat and once it did update the data internally,
it will call this component function again and execute the entire function and hence also re-render this
jsx code.
Now under the hood, it will not re-render the entire DOM, it will just check which parts of the DOM need
to be updated but it will re-evaluate the entire component.
This also means of course that it re-executes use state but use state internally works such that it
only initializes that state when the component is rendered for the first time and for subsequent
re-render cycles, it just pulls out the latest state snapshot and basically ignores the initial value we
set up here.
This is how state works.
Now it is also important to understand that this way of updating our state in this scenario is not the
best possible way,
so I'll duplicate it and comment it out
so that we still have it for reference
but we also see the better approach.
This approach clearly works and in most cases it will work but you have to be aware that this whole
state updating re-rendering part of React is in the end managed by React
and when you set a new state, it doesn't pause everything and immediately re-render your app, instead
it schedules the state update
and if you have an application with a lot of ongoing state updates and a lot of work being performed,
which is not the case in this application but can be the case in other applications, then your state
update might be deferred by a few milliseconds.
That means that actually maybe if a user clicks add goals multiple times, the course goals which are currently
rendered on the screen might not be our latest state because not all state updates might have been processed
yet,
therefore there is a better form of updating this, instead of passing our new state data to set course
goals,
you can pass a function to set course goals, a function which receives the latest state, pref course goals
and has to return a new state snapshot and React will then schedule all these function calls and guarantee
you that they are executed in the right order so that even if a state update was deferred, by the time
the update thereafter executes, it guarantees you the first one executed as well
and then here you would simply date for return pref course goals which still is an array
concat new goal. It will yield the same result as before in this app and in this simple app,
this approach would have been fine,
there is basically no chance of React deferring updates so long that
we would end up with an incorrect state but this is the bulletproof approach which will always work.
You only need it if your state update depends on the previous state's data
as this one does,
if your state update is a new data piece which doesn't depend on the previous state, you can always
safely use this non-functional form.
And here, side note, we can of course also shorten this, take advantage of arrow function syntax and
get rid of the return statement and the curly braces since we have only one expression which we immediately
return.
So now with that, it works as before but this is a bit of a safer approach and the recommended approach
if your state update depends on the previous state.