[Maximilian] So that's how we can useState.
And the special thing really is
that when you update your state
the component function gets executed again
and therefore the latest JSX snapshot gets
used by React, gets compared to the previous
snapshot and the UI is updated where needed.
Now, here, however, the goal was to basically get
this text into this first post component.
And of course that's not happening right now.
One problem we're facing here
is that this state is inside the NewPost component.
That's great, but we don't need it there.
Instead, we need it in the PostsList component
so that we can set this entered text
as a value for this body.
Now, how do we get the state from NewPost to PostsList?
Well, an obvious solution would be to import useState
from React in the PostsList component
and register the state there.
We could have the EnteredBody here
with help of useState.
And this should use object destructuring
here to get the EnteredBody
and the set EnteredBody state updating function.
Now we have the state in the component where we need it
and we could set this body to the value
that's currently stored in EnteredBody
so that our current state value is output down there.
That's amazing and great and theoretically
that's a good approach but now we have the state
in the right place, but the event
is in a different component.
So how can we solve this puzzle?
We either have the state or the event
in the wrong component.
Well, what we have to do here
and what we already started doing
is something that's called lifting the state up.
If you have state that's manipulated in component A
but needed in component B, you should lift the state
up to a component that has access
to both components that need the state.
So in this case, it's the PostsList component
that needs the state to pass it to post
as a value for the body prop.
And it's also the PostsList component that has access
to the NewPost component
which is the place where the state should be manipulated.
Now what we can do in this case
is we can get rid of the state here
in NewPost
and get rid of the event handler function
and the useState import as well.
And we could now simply use this props feature.
So this props object, which we get
by React automatically
to set this onChange event listener prop
equal to, for example,
props.onBodyChange.
Now this prop name is up to you
because you can set any props you want
on your own components.
With that prop being set like this
on the onChange prop of text area,
we can go to PostsList and on NewPost
we can now add the onBodyChange
prop here
to the NewPost component.
And as a value we can now again pass in a function
that should be called when the text area changes.
So when the change even occurs on the text area.
In this case, for example
the bodyChangeHandler
where we automatically get the event object as before,
and where we then call set EnteredBody
equal to event.target.value
and it's then the bodyChangeHandler function
which is passed as a value to onBodyChange, to this prop.
Now this might be confusing at first
but what I'm doing here is I'm passing this
bodyChangeHandler function to onBodyChange.
So we're not executing it here, we have no parenthesis.
Instead, I'm using this function bodyChangeHandler
as a value that's passed to the onBodyChange prop.
Now in the NewPost component,
I'm then in the end forwarding that value
that's received on the onBodyChange prop
as a value to the onChange prop of text area.
So we simply pass that function,
that bodyChangeHandler function,
through the NewPost component
with help of the onBodyChange prop
to the text area component.
And this should all be quite a bit less confusing
if you keep in mind that functions can be used
just like any other kind of value in JavaScript.
So therefore, in the end here,
we wire up this bodyChangeHandler function
to this change event on text area.
That's why we also still get this event object.
And with that we can now update the state in the component
where we need it while still setting the listener
in the component where the event occurs.
And of course, we can also do that
with the author input.
There, we can add the default onChange prop
to add a change event listener to that input as well.
And for example, expect to get a function value
on the onAuthor change prop.
Again, this prop name is up to you
because it's your component.
But with this prop chosen here inside of NewPost
we now have to use the same prop name here
on the NewPost component in PostsList
and then copy that bodyChangeHandler function
and name this copy authorChangeHandler, for example
to then pass this authorChangeHandler function
as a value to the on author change prop.
And then again, that's picked up
and used as a value for the onChange prop inside of
that NewPost component.
Now we just need to register a second state slice
for that author name
and that is something you can do.
You're not limited to one single state per component.
Instead you can have as many state values as you need.
So here we can simply call useState again to register
a second state value for this component.
And this also is an empty string initially,
but then we get back two values again
or one value, one array with two elements to be precise.
That's my entered author.
And then my updating function, which could be called
setEnteredAuthor.
And whenever any of these two states changes,
this PostsList component function will be executed again.
In that case, the entire JSX code down there is evaluated
again, which means that any nested component functions
are also executed again.
And that leads to precisely the behavior we want
because that means that this post
where we pass our updated state values
as values for its props to that post component function,
this post component function will also be executed again
if PostsList executes again
and therefore these updated values
which we pass as values to props to this component
will be reflected in the JSX code of that component
and hence the UI will be updated accordingly as well.
So that's how UI updates work with help of React and state.
So therefore here I now wanna pass my enteredAuthor
as a value for the author prop
for this first post component.
And then here in authorChangeHandler,
I call setEnteredAuthor and pass event.target.value
as a value.
With that done, we just have to go to NewPost
and get rid of this paragraph with EnteredBody
in there because we no longer have the EnteredBody state
in that component.
And if you then save everything,
you see that this component is empty by default,
which should make sense because our default states
for EnteredBody and enteredAuthor are empty strings.
But as soon as I start typing something here
into these input fields, you see that the component down
there gets updated dynamically with every key stroke
because of state and because we lifted state up
into a place where we can update and use it.