State is a crucial concept in React and with our knowledge about state, we can now also make sure that
we don't just create a dummy goal but we actually reflect the real user input.
So for that, let's go back to new goal.
What do we want to do is we want to store the user input in some variable on every keystroke so that
we have the latest value entered by the user and then pass that entered value to props on add goal or
to our new goal here instead of that hardcoded dummy text we have at the moment.
So here in new goal, I want to capture the user input here and send this instead of my hardcoded text
here as part of the new goal.
So we could create a variable here,
user input or entered text maybe, which is an empty string initially and here on input, there actually
is an on change event we can listen to which is fired on every keystroke.
So now we can add a function,
text change handler, there we will get an event object and that event object will hold the user input, on
event target which refers to the input element, .value and therefore we could set enter text equal to
that. Now entered text will change with every keystroke
once we bind on change to text change handler, like this.
Now here in new goal, we can use entered text,
so what the user entered here and thereafter let's also console log the new goal here so that we
can see that this works. If we now save this and I enter test here and I click add goal, we see this works
and this is output here. This approach is generally fine but it can have one tiny flaw,
what if we want to reset this
after adding a new goal? Of course we can go to our add goal handler and once we created the new goal,
we can of course set entered text back to an empty string
but of course this won't do anything.
If I enter this goal, you see this is not reflected here,
why is it not reflected?
Because the new goal component didn't re-render,
this is not state we're managing, this is a regular variable,
so of course we can change it,
of course we can use the changed value but if we then set a new value to it,
this is not reflected on our input because this input only has a connection to the text change handler,
it does not know that it should reflect the current value stored in entered text.
Now we could tell the input component that it should do so by binding its value prop, we can bind this
to entered text and with that we tell the input component, hey the value displayed in the input should
be the value stored in entered
text. If we do that, we'll notice something new,
now we can't type there anymore, if I type here,
the input is not reflected.
Now if you think about it, that makes sense.
What you're telling React is that input should be rendered such that the value is the entered text, with
every keystroke we change entered text but entered text is not state, it's a regular variable.
So that means that we change the variable with every keystroke but React doesn't re-render the input
component, it doesn't reflect the updated value. To React, the value always is an empty string because that
was the last time it rendered this component and therefore this jsx code and therefore this input.
So we need to tell React that this is some state and that when it changes, it should re-render our
jsxcode.
So again we can import use state here and convert entered text, use array destructuring here and use state
is an empty string initially or has an empty string initially here because I'm managing my entered text
and the second element is a function to update the state which I'll therefore call set entered text.
And now here on every keystroke, I set my entered text to the value in event target value
and here we don't need that function form of updating the state because we have a brand new value that
doesn't depend on the previous state,
so we can just update to state like this and now this will re-render this component whenever we type,
whenever we call set entered text, so on every keystroke, which sounds horrible but which is great, React
will do this in a very efficient way and therefore this latest value will be reflected on the input
element and here in add goal handler, if we want to update entered text and reset it, we can therefore call set
entered text and set it back to an empty string
and with that, we now have the best of both worlds. We can enter something here, that all works but we also
can manipulate it and reset after adding a new goal, like this.
So this is now another use case for state management
and of course there are many use cases in a React application
and here we are using state management to create something which is also sometimes called two-way binding.
We're binding the value of the input and on every keystroke, we're updating to value which we then bind
back to the input, so that we always reflect the latest value inside of the input but we also are able
to manage this in a state-driven way
so that we also have a chance of manipulating the value from inside our code up here and reflect this back
into the input in this case. With that, we have another scenario of state management and we are now able
to add our own goals.