Use the spread syntax on collections of dynamic data to copy the previous state into the next state like so: setArrayState((prev) => [ ...prev ])
and setObjectState((prev) => ({ ...prev }))
#1
Is this: setArrayState((prev) => [ ...prev ])
means this: setArrayState(function(prev) { return [ ...prev ] })
?
#2
Also, I don’t understand the role of the spread syntax here: [...prev]
What does it help to accomplish?
The remark you posted from the Codecademy instructions is a bit incomplete. What they really meant to say is that
This is what they meant to say but probably for brevity sake just didn’t flesh it out completely. If we don’t intend to make any modifications to prev, then using the spread syntax doesn’t make sense.
As for #1, yes there is an implicit return going on. In the setArrayState example, we take the previous array and then implicitly return a new array. This new array will have some new element(s) and the already existing elements will be unpacked from the prev array using spread syntax.
In the setObjectState example, again there is an implicit return of an object. Since Javascript looks at the curly braces in this context as designating the body of a function, so we can’t just use curly braces. We have to wrap them in parentheses so that Javascript knows that this is meant to be an object and not the body of the arrow function. Have a look at this article. It is a short read, but it explains the issue very nicely with examples.
As for #2. Suppose prev is an array consisting of ["Carrots", "Kale"]. We want to update the state by adding a new element “Lemons”. If we just did setArrayState((prev) => [ "Lemons" ]), then a new array will be created and implicitly returned and the previous array will be lost. However, if we use spread syntax like this setArrayState((prev) => [ "Lemons", ...prev ]), then the new array will be ["Lemons", "Carrots", "Kale"] which is what we want. We want to preserve the existing data, not overwrite it. You can read more about the spread syntax here.
Hey everyone, this bit has been particularly confusing and difficult. Could someone please explain some things to me?
Why do we need two event handlers, handleChange and handleSubmit? Why not just let the user input whatever they want, then use handleSubmit to add it to the list? That way, we wouldn’t need newTask either, only allTasks. On a similar note, what is the significance of having handleChange? Is it called every time the input field changes (every single press of a character on the keyboard)?
I’m sure I’m missing something, please help! Thanks!
That pattern is pretty common in React - handleChange and handleSubmit. Forms are done using controlled components a lot of times in React. If you look in the component under /Presentational/NewTask.js you will see that handleChange is connected to the onChange attribute for an input element. And there you can also see handleSubmit being triggered by the onSubmit attribute for the form. So basically, handleChange will update the “new” task every time it is updated (yes, every single key). And handleSubmit will add the task to the allTasks array once you press enter to add the task.
Thank you for the clarification!
I still can’t fully understand why handleChange is needed though. I imagine if we didn’t have it, and the input element didn’t have an onChange attribute, and we only had handleSubmit, upon which the string to be submitted is taken and used, it feels like it’ll still work fine? Why do we have to handleChange every time the most minor change occurs, instead of waiting for the final input? It’s not like the DOM is updating with every key press (The input field is simply a HTML input tag, not dynamically updating via React and JSX every key press… right?)
Sorry if something I said in there is ridiculously stupid, and thanks again!
It is just a common way in React - using controlled component. Gives access to the value in the form at all times. Here is the official React docs talking about forms: https://reactjs.org/docs/forms.html
And as you see there in the form docs the main example is using this technique with handleChange/handleSubmit. It also talks about why it’s done that way commonly. But you can do it with uncontrolled components as well - also in the docs. In a bit larger apps you may end up using a library anyway such as formik or react-hook-form.
And as the project is built - the handleSubmit depends on the newTask state being updated correctly - which is done by handleChange.
Thanks!
Another question: Why do we need the prevState parameter in the callback of a setState function? e.g. in setCount, why define a parameter in its callback prevCount, instead of simply using count?
Since the state is updated based on the previous state. We had a previous array of tasks in allTasks. Then we add one more task to this state. We need to use this parameter (which they called prevState) to reference the previous state and add the new task to that previous state. In some other cases, you may not need to reference previous state (and then the parameter to the callback is not required). For example when you have a selectedTask state or something like that (which may just contain one integer - the task id for example). So you got 2 scenarios for state update - those that depend on previous state and those that don’t.
felt like this part of the course just throws you in the deep end especially the final lesson. really bad introduction to hooks when alot of the code isnt really explained and the steps dont really help with whats going on. really enjoyed React up to this point of the course and hope it will be updated to be more helpful in the future.
In the index.js file it says: import App from "./Container/AppClass";
But if you go into the AppClass file in the Container folder, App is not being exported. “AppClass” is being exported - not “App”. Actually the word “App” does not even exist in the entirety of that file…so how is it importing “App” from “./Container/AppClass” when “App” doesnt even exist. where is “App”?
Is this an error by Codeacademy or am I misunderstanding something?
I think its extremely confusing because of the wording…
you have to think in terms of the previous state’s “new task” (which is technically the old/first input i.e. the title) vs the new “new task” which is the new task including both the first input (title) and the second input (details) (?)…so it’s not a “new task” per se but an additional detail of the same task. That’s why it was so confusing at first.
Is it correct to assume that it would be much easier to understand the whole thing, if they re-wrote the code using some reference to “taskTitle” and “taskDetail” instead of using just “newTask”?
you can and it will work but as mention in lesson it is a safe practice , you can review it below
" Note: We can just call setCount(count +1) and it would work the same in this example… but for reasons that are out of scope for this lesson, it is safer to use the callback method. If you’d like to learn more about why the callback method is safer, this section of the docs is a great place to start."
same problem here, this whole chapter on hooks is an absolute piece of ■■■■, not only do they waste your time learning class components, you dont learn it in depth enough so that you can then take a class component and transform it on a functional component. Its garbage.
100%, I was enjoying this course until up to this section, it’s absolute garbage, thankfully I could resort to Youtube to learn a lot more about hooks and just ignore this garbage lesson. I’m really angry at it to be honest.
I am doing the Full Stack '21 course. This was the first time I have felt so confused and overwhelmed. I did not understand anything. Instructions were full of waffle and failed to teach me anything. Sadly this was a total waste of time and I will have to research hooks myself to learn this concept.