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
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
So far, we restructured our state to
be entirely in the main App component.
0:00
But in doing so, we lost a functionality
of the Counter component.
0:06
The buttons no longer
modified the score state.
0:11
Counter needs to alter a piece of state
that lives way above it in the main App
0:14
component.
0:19
We learned about React's
unidirectional data flow.
0:21
So if data flows down,
how can a child component
0:24
like Counter get information back
up to its ancestor component?
0:28
To do that, the parent can pass
down a callback function as a prop.
0:34
Callback functions allow you
to communicate events and
0:39
changes to your data, upwards,
while data continues to flow downwards.
0:42
Let's refactor the Counter
components event handlers.
0:47
In order to design how data flows
upwards through the component tree,
0:52
we need to think about each component and
its responsibilities.
0:56
Counter, for example, has score
passed to it by its parent, Player.
1:02
And Player gets the score from its parent,
App.
1:07
The App component
maintains the score state.
1:13
And the buttons intended to change
the score are two components deep from
1:16
the App in Counter.
1:21
[SOUND] Since data in
React flows downward,
1:22
a child component has no way to
directly communicate to its parent.
1:25
But React allows us to use props that
are callback functions to communicate data
1:30
upstream from a child to a parent.
1:35
For example, we can write event
handlers that manipulate state and
1:38
pass them down to components
as callback functions.
1:42
When a child wants to indicate that
the application state should change, like
1:45
clicking a button to change the score,
it will execute the callback function and
1:49
the parent will know what
to do to update the data.
1:53
In fact, this app already implemented
a simple version of this.
1:58
The handleRemovePlayer function in
the App component gets called down in
2:03
the Player component when the user
clicks the delete button.
2:07
The Player component has access to the
function written in the App component, and
2:15
can pass data up to it via the callback
function passed as a prop.
2:20
We're gonna move the counter event
handlers up to the App component.
2:25
We'll refactor the two functions
into one handleScoreChange function,
2:30
that changes the score state
based on the data passed to it.
2:34
First, I'll uncomment
both of the functions.
2:40
I'm gonna copy the incrementScore
function and delete both,
2:45
since we only need just one function.
2:49
I'm gonna save and navigate to App.js.
2:52
Under the handleRemovePlayer
function is where I'll paste
2:55
the incrementScore function.
2:59
I'll change the name of
the function to handleScoreChange.
3:01
Instead of increasing or decreasing
the score state by specifying +1 or
3:10
-1, the function will accept an argument
that specifies a change or delta in score.
3:16
l'll pass handleScoreChange,
the parameter delta.
3:24
I'm choosing the name delta because
a delta is the variation of a function.
3:28
In our case,
the number the score should change by.
3:33
You can give this parameter
any name you want.
3:38
For now, I'll comment out the setScore
method and console.log the value of delta.
3:42
Next, we need to pass
the handleScoreChange function down
4:00
to the Counter component with props.
4:04
First, we'll pass it to
the Player component,
4:06
then supply it to the Counter component.
4:09
The function will then be called inside
the counter, using the onClick event.
4:11
In the map function, let's give the Player
component a new prop named changeScore.
4:19
Then pass it
the handleScoreChange function.
4:30
This callback is going to run at a later
time through some interaction with
4:40
a child component.
4:45
Let's save our changes in the file,
Player.js.
4:46
We'll pass a function down to
the Counter component using props.
4:49
In the return, give the Counter
component a prop named changeScore.
4:55
And pass it the function
with props.changeScore.
5:05
Now the function is
available to be called or
5:12
invoked from inside the Counter component.
5:15
When a button in the counter is clicked,
the function will be executed,
5:19
passing in the number
the score should change by.
5:24
We'll save and navigate to Counter.js.
5:28
Let's once again provide
an onClick event to each button.
5:31
I'll pass onClick an anonymous
function that calls props.changeScore.
5:37
Then I'll pass it the delta argument,
5:46
which is the number to
change the score by.
5:49
For the minus button we'll pass -1.
5:53
We can do the same for the plus button,
and make it change by +1.
5:58
The handleScoreChange function in the App
component knows how to change the score.
6:06
If we run our code and open up the
console, clicking a plus button logs a 1,
6:13
and each click of
the minus button logs a -1.
6:19
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up