So now we know
how we can set up event listeners.
Let's now dive into this state concept.
And to get started, I simply wanna output the text
that's input into this textarea
in a new paragraph below this input in the end.
We'll soon also make sure
that it ends up in the post component,
but for the moment let's just output it there.
To achieve this, we need to store the value somewhere
and then reference that somewhere down there.
And the first thing you might think about
could be a variable.
We could add a variable enteredBody
which maybe is an empty string initially.
And then here instead of console logging the entered value,
we could store it as a value in enteredBody like this.
So we update the variable
whenever this function is executed,
which happens on every keystroke as we saw.
And then we could use this enteredBody variable
down there in this paragraph.
So here we can use our single curly braces
and output enteredBody.
So this variable is updated here
and is then output down there.
Should work, right?
Well, if you save that
and you type something here, nothing happens.
It should be output down there
because that's where I added the paragraph.
And indeed, if you inspect this here,
you will see that below this textarea here
is an empty paragraph
but it is indeed that, empty.
What I type here is not being output in that paragraph.
Now why is that the case?
Well because there is something
very important to understand.
React executes your component functions like NewPost
and it then takes the JSX code returned by those functions.
So the current snapshot of the HTML content
that should be output on the screen
and it does render it to the screen.
But if thereafter in your component function
you change some variable value
that's being used in your JSX code,
that won't be picked up by React
because this JSX code is only taken once as a snapshot
when this component function is executed for the first time.
Indeed, if that component function
would be executed by a React again,
it would also consider any updates to that snapshot
and update the rendered user interface.
But React does by default
not randomly execute NewPost again.
And it does not execute NewPost
or any other component function again
just because you changed some variable
or just because you have some event listener in there.
This is ignored by React.
Of course it adds the event listener
and this function executes, but it does not care
about whether this would theoretically change your JSX code.
Instead, you have to basically create this variable
in a special way using a special React feature
to let React know about any changes
that should cause a UI update.
And for that you have to import something from React.
So from the React library, not from React DOM,
but from just React.
And that something is a function called useState.
Now this is a so called React Hook.
React has multiple built-in functions
that all start with use,
as you can see here with my auto completion.
And these functions,
whilst technically being standard JavaScript functions
are called React Hooks.
So functions in React that start with use
are considered React Hooks.
The special thing about these hook functions
is that you must execute them inside of component functions.
You can't execute them in regular JavaScript functions.
You can, but you'll get a warning or an error.
But you must execute them
in React component functions instead.
And then those hook functions typically
change something about that component
or regarding how React behaves with that component.
In case of useState when you execute that
inside of a component function,
you register a new state slice, as you could say.
A new state value that belongs to this component.
In a state value can be anything.
It can be an object, a number, an array, a string,
whatever you want.
Here if you wanna store the entered text,
we could register a string as a state slice
for this component.
You set a default value for that state variable
if you want to call it like this,
by passing your initial value as an argument to useState.
For example an empty string just as I did it down there.
But again, that could be anything.
It can be undefined, it can be a number,
it could be an object, but here it's a string.
useState then returns something.
It returns an array.
And I'll store that array in a constant.
StateData is a name we could use here.
Now this stateData array
has always exactly two elements,
never more, never less.
And the first element of stateData
is always the current state value.
So initially that empty string
but that value can change as you will soon see.
Because that second element in that stateData array
is a state updating function.
A function which you can execute to assign a new value
to your state.
Because that state value is stored
somewhere in memory by React.
You set an initial value
and you can then call this function,
which is returned by useState as a second element
in this stateData array to update that value.
Now the special thing about that is,
that if you call that state updating function,
you don't just store a new value somewhere in memory
but React will also reexecute that function
in which this state was registered.
So it will call this component function again,
just as it did initially when it rendered that component
for the first time.
And since it calls that component function again,
you get the current state value.
So the value which you just set
with help of that state updating function
as the first element here.
And you get the latest JSX snapshot.
And if that deviates
from the previously rendered JSX snapshot,
React will update the parts in the UI that need updating.
And that's, by the way, all important.
React will basically make a comparison
between the different snapshots behind the scenes
and only update the parts in the UI that must be updated
so that you don't unnecessarily update the DOM,
which is quite performance intensive.
So that's what you get back here.
Now it's quite common to use array destructuring here,
which is a default modern JavaScript feature
to store the current value in a constant
and the updating function.
And typically you should pick names here
that describe your state,
like for example, the enteredBody.
And then the updating function
could be called setEnteredbody.
It's kind of a convention to name
this state updating function set,
and then you basically repeat your state name,
just format it as camel case.
Now I'll remove that variable here
because we have a name clash otherwise.
And with that we registered this state.
Now to update that state
you don't try to assign a new value.
That's why I also use the const here for these two values.
Because instead you have to call
this state updating function, setEnteredBody,
like this and pass your new value
as a value for this argument to setEnteredBody.
Then behind the scenes, the new state value is stored
and this component function is executed again
and enteredBody will then hold that new value.
That's why it may be a constant
because it's always a brand new constant
because it's always a brand new function execution
in the end when you update the state.
So now we can use this enteredBody state here
in this paragraph to output the new state value.
But this time because we're using this state feature
provided by React with help of the useState hook,
this will all work.
And if I now save everything again,
you will see that as I type something here,
it updates down there below the text input.
So this works now.
And with every keystroke this gets updated as you can see.
Now that's Reacts state feature in action.