As per my understanding (which can be wrong. Hopefully someone will correct me if that is the case), in the code
const [cart, setCart] = useState([]);
the useState
hook will assign the empty array as an initial value to cart
and designate cart
as the current state.
setCart
is a function which can be used to update this state. We don’t have to define the setCart
function. The useState
hook takes care of this. setCart
is already a function built into the useState
hook and its code is not visible to us explicitly. If we simply call this function with a value, then setCart
will overwrite the old state with this new value e.g. setCart(['Strawberry'])
will replace the old cart with a new cart consisting of just this one element. By writing the statement setCart(['Strawberry'])
, we aren’t defining setCart
. We are calling the setCart
function with ['Strawberry']
as an argument.
As opposed to overwriting the old state, if arriving at the new state requires use of the old state, then we can do as shown in the snippet:
setCart((prev) => {
return [item, ...prev];
});
Again, we aren’t defining the setCart
function. It is already defined somewhere in the internal useState
hook code hidden from us.
(prev) => {
return [item, ...prev];
}
is a function but it isn’t being used to define the setCart
function. setCart
is already defined somewhere hidden from our view. That hidden code defines setCart
in such a way that if setCart
is called with a value, then it simply overwrites the old state with this new value. However, if setCart
is called with a function with a parameter, then setCart
will assign the old state to the parameter of our function and then whatever value is returned by our function, setCart
will overwrite the old state with this returned value. Howsoever setCart is defined by useState’s hidden code makes it able to distinguish how it is being called and how it should proceed from thereon.