Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
In this video, we'll refactor the Counter's event handlers, and implement new props in the Player and Counter components that will act as callback functions.
Resources
We've restructured our state to be
entirely in our main app component.
0:00
But we've lost our
functionality of the counter,
0:04
the counter buttons no
longer modify the score.
0:06
The buttons in the counter need to alter
a piece that state that lives in the app
0:09
component.
0:14
Now, if data flows down in React,
how does a child component like
0:14
counter get information back
up to its ancestor component?
0:19
Instead of passing state
to a child component,
0:23
the parent can pass down
a callback function.
0:26
The callback will allow you to communicate
events and changes in your data upwards,
0:29
while data continues to flow downwards.
0:34
So next, we'll refactor the counter's
event handlers, and implement new
0:36
props in the player and counter components
that will act as callback functions.
0:41
In order to design how data flows
upward through our component tree,
0:46
we need to think about each component and
its responsibilities.
0:49
Counter, for example,
has a score passed to it by its parent,
0:53
the player component and player gets to
score from its parent, the app component.
0:58
The app component maintains the score
state and the buttons intended to
1:06
change the score are two components
deep from app in the counter.
1:11
Since data in React flows downward,
1:16
a child component has no way to
directly communicate to its parent.
1:19
But React allows us to use props that
are callback functions to communicate data
1:23
upstream, from a child to a parent.
1:28
For example, we can write event
handlers that manipulate state, and
1:30
pass them down to component
as callback functions.
1:34
When a child wants to indicate that
the application state should change,
1:37
like click a button to change the score,
it will execute the callback function and
1:41
the parent will know what
to do to update the data.
1:45
In fact, we've already implemented
a simple version of this.
1:48
We wrote the handleRemovePlayer function
in the app component which gets
1:51
called down in the player component
when the user clicks the delete button.
1:56
The player component has access to
the function written in the app class and
2:01
can pass data up to it via the callback
function passed as a prop.
2:08
So now we're going to move the counters
event handler up to the up component.
2:14
We'll refactor the two functions into
one handleScoreChange function that
2:20
changes the score state based
on the data passed to it.
2:24
First I'll uncomment the increment score
function, cut it out of counter.js and
2:28
paste it inside the app component just
above the handle remove player function.
2:33
You can delete the decrementScore function
in the counter since we just need one
2:39
function for this.
2:43
Back in app.js I'll change the name of
the function to handleScore change.
2:44
And instead of increasing or decreasing
the score state by specifying +1 or
2:54
minus 1, the function will accept
an argument that specifies the change or
2:59
delta and score.
3:04
I'll pass handleScoreChange,
the parameter, delta.
3:06
And I'm choosing the name delta because
a delta is the variation of a function,
3:09
in our case the number
the score should be changed by.
3:14
You can give this parameter
any name you want.
3:17
For now,
I'll comment out the setState method, and
3:19
console.log the value of delta.
3:22
Next, we need to pass
the handleScoreChange function down to
3:28
the counter component with props.
3:32
We'll first pass it to
the player component,
3:34
then supply to the counter component.
3:37
A function will then be called inside
the counter using an onClick event.
3:39
So in the map function,
3:43
let's give the player component
a new prop named changeScore.
3:45
Then pass the handleScoreChange
function with this.handleScoreChange.
3:51
This callback is going to run at a later
time through some interaction with a child
3:58
component.
4:03
So in the file, Player.js,
4:04
we will pass the function down to
the counter component using props.
4:06
In the return, let's give the counter
component a prop named changeScore and
4:10
pass it the function
with props.changeScore.
4:18
So now the function is available
to be called, or invoked,
4:26
from inside the counter component.
4:30
When a button in the counter is clicked,
4:33
the function will be executed passing in
the number the score should be changed by.
4:35
In Counter.js, let's once again provide
an onClick event to each button.
4:40
I'll pass onClick an anonymous
function that calls props.changeScore.
4:48
Then pass it the delta argument, which
is the number to change the score by.
4:56
For the minus button we'll pass -1.
5:00
We can do the same for the + </button>,
5:05
and make it changed by positive 1.
5:10
So now, the handleScoreChange
function written in the app
5:14
component knows how to change the score.
5:19
If we run our code, and
open up the console,
5:22
clicking a + button, logs a 1,
and each- button logs a -1.
5:27
You need to sign up for Treehouse in order to download course files.
Sign up