1
00:00:03,000 --> 00:00:05,955
We've seen before, in the section on Rendering,

2
00:00:05,955 --> 00:00:07,842
that if we need to use any

3
00:00:07,842 --> 00:00:09,729
client-side functionality,

4
00:00:09,801 --> 00:00:12,650
we need to add the "use client" directive

5
00:00:12,650 --> 00:00:14,248
at the top of the file,

6
00:00:14,317 --> 00:00:17,281
to mark this as a Client Component.

7
00:00:17,281 --> 00:00:20,395
With this simple change, the error goes away.

8
00:00:20,395 --> 00:00:23,022
But let's make sure we fully understand

9
00:00:23,022 --> 00:00:24,437
what's going on here.

10
00:00:24,504 --> 00:00:28,070
If we comment out the "use client" directive,

11
00:00:28,070 --> 00:00:31,402
then this will be treated a Server Component,

12
00:00:31,402 --> 00:00:33,520
and if we save, we get an error,

13
00:00:33,520 --> 00:00:37,224
because we cannot use client-side functionality

14
00:00:37,224 --> 00:00:38,957
in a Server Component.

15
00:00:39,036 --> 00:00:41,265
Note that the error started when

16
00:00:41,265 --> 00:00:43,424
we added the "onClick" handler.

17
00:00:43,494 --> 00:00:46,036
If we remove this, then everything

18
00:00:46,036 --> 00:00:47,232
works just fine,

19
00:00:47,307 --> 00:00:49,197
because there's no longer any

20
00:00:49,197 --> 00:00:50,891
client-side functionality,

21
00:00:50,956 --> 00:00:52,872
and so this component can be

22
00:00:52,872 --> 00:00:54,788
rendered only on the server.

23
00:00:54,856 --> 00:00:57,113
Let's add a log statement here,

24
00:00:57,113 --> 00:00:58,881
printing a message any time

25
00:00:58,881 --> 00:01:00,650
this component is rendered,

26
00:01:00,773 --> 00:01:04,855
just to remind ourselves of how rendering works.

27
00:01:04,855 --> 00:01:07,055
By default, all our components

28
00:01:07,055 --> 00:01:08,667
are Server Components,

29
00:01:08,741 --> 00:01:11,753
meaning that they only render on the server.

30
00:01:11,753 --> 00:01:14,767
There are no messages in the browser console.

31
00:01:14,767 --> 00:01:17,980
With the "use client" directive however,

32
00:01:17,980 --> 00:01:20,278
ShareLinkButton will be treated

33
00:01:20,278 --> 00:01:21,909
as a Client Component.

34
00:01:21,983 --> 00:01:24,131
This means that it will be rendered

35
00:01:24,131 --> 00:01:26,789
both on the server and in the browser.

36
00:01:26,789 --> 00:01:28,856
Let's see how this works in

37
00:01:28,856 --> 00:01:30,846
terms of network requests.

38
00:01:30,922 --> 00:01:33,657
I'll comment out "use client" again,

39
00:01:33,657 --> 00:01:35,898
so we can start with the Server

40
00:01:35,898 --> 00:01:37,272
Component behavior.

41
00:01:37,345 --> 00:01:39,575
If we look at the Network requests,

42
00:01:39,575 --> 00:01:40,977
when we open the page,

43
00:01:41,041 --> 00:01:43,447
we know that the browser first

44
00:01:43,447 --> 00:01:45,373
loads the HTML document.

45
00:01:45,453 --> 00:01:48,219
And the Next.js server pre-renders

46
00:01:48,219 --> 00:01:50,823
the HTML for all our components,

47
00:01:50,905 --> 00:01:53,367
including ShareLinkButton.

48
00:01:53,367 --> 00:01:56,192
Since it's currently a Server Component,

49
00:01:56,192 --> 00:01:58,493
no JavaScript code will be sent to

50
00:01:58,493 --> 00:02:00,590
the browser for this component.

51
00:02:00,658 --> 00:02:03,585
So we see the button displayed on the page,

52
00:02:03,585 --> 00:02:06,514
as rendered from this HTML code,

53
00:02:06,514 --> 00:02:09,377
but we cannot have any actual functionality

54
00:02:09,377 --> 00:02:10,908
attached to the button,

55
00:02:10,976 --> 00:02:14,207
because the browser doesn't have any JavaScript

56
00:02:14,207 --> 00:02:16,682
code associated with that component.

57
00:02:16,751 --> 00:02:20,421
Now, let's turn it into a Client Component again,

58
00:02:20,421 --> 00:02:23,454
and see what happens if we reload the page.

59
00:02:23,454 --> 00:02:27,297
The first request will still be the HTML document,

60
00:02:27,394 --> 00:02:29,571
and the ShareLinkButton was still

61
00:02:29,571 --> 00:02:31,352
pre-rendered on the server.

62
00:02:31,418 --> 00:02:34,845
However, since it's now a Client Component,

63
00:02:34,845 --> 00:02:36,707
the browser will also receive

64
00:02:36,707 --> 00:02:38,055
some JavaScript code,

65
00:02:38,119 --> 00:02:40,416
that should include the function where

66
00:02:40,416 --> 00:02:42,169
we log the "clicked" message.

67
00:02:42,230 --> 00:02:44,464
This code contains the full

68
00:02:44,464 --> 00:02:46,532
ShareLinkButton function.

69
00:02:46,615 --> 00:02:49,073
After loading this JavaScript file,

70
00:02:49,073 --> 00:02:51,683
the browser runs the component function,

71
00:02:51,683 --> 00:02:54,928
rendering our component on the client-side.

72
00:02:54,928 --> 00:02:56,614
In fact, in this function we

73
00:02:56,614 --> 00:02:58,301
log a message to the console

74
00:02:58,361 --> 00:02:59,993
saying "rendering".

75
00:02:59,993 --> 00:03:02,401
And we do see that message printed

76
00:03:02,401 --> 00:03:04,029
to the browser console,

77
00:03:04,100 --> 00:03:06,852
proving that the browser is executing

78
00:03:06,852 --> 00:03:09,008
our ShareLinkButton function.

79
00:03:09,083 --> 00:03:11,163
So, the browser has the full

80
00:03:11,163 --> 00:03:12,947
code for this component.

81
00:03:13,021 --> 00:03:14,951
That's why we can now include

82
00:03:14,951 --> 00:03:16,682
client-side functionality,

83
00:03:16,748 --> 00:03:19,876
like an "onClick" handler for the button.

84
00:03:20,068 --> 00:03:21,546
If we reload the page,

85
00:03:22,068 --> 00:03:24,500
when we click the button we'll see that

86
00:03:24,500 --> 00:03:26,604
our handler function is called,

87
00:03:26,604 --> 00:03:28,709
and logs the "clicked" message.

88
00:03:28,777 --> 00:03:30,825
Of course, it will be called again

89
00:03:30,825 --> 00:03:32,572
whenever we click the button.

90
00:03:32,632 --> 00:03:34,766
Now, the process of rendering

91
00:03:34,766 --> 00:03:36,753
a component in the browser,

92
00:03:36,826 --> 00:03:39,798
after it was already pre-rendered on the server,

93
00:03:39,798 --> 00:03:41,828
is called "hydration".

94
00:03:41,828 --> 00:03:44,185
It is a bit different from rendering

95
00:03:44,185 --> 00:03:46,280
a component only in the browser,

96
00:03:46,345 --> 00:03:47,984
like in traditional React

97
00:03:47,984 --> 00:03:49,622
Single Page Applications,

98
00:03:49,687 --> 00:03:52,041
because in this case we already

99
00:03:52,041 --> 00:03:53,787
have some initial HTML,

100
00:03:53,863 --> 00:03:55,766
generated by the server,

101
00:03:55,766 --> 00:03:57,748
with all the elements for our

102
00:03:57,748 --> 00:03:59,661
ShareLinkButton for example.

103
00:03:59,729 --> 00:04:03,536
After loading and displaying that initial HTML,

104
00:04:03,536 --> 00:04:06,625
the browser will then load the JavaScript code.

105
00:04:06,625 --> 00:04:09,760
And it will execute our component function,

106
00:04:09,760 --> 00:04:12,064
rendering a client-side version

107
00:04:12,064 --> 00:04:13,700
of the same component.

108
00:04:13,774 --> 00:04:16,439
It will be almost the same as the

109
00:04:16,439 --> 00:04:19,024
HTML pre-rendered by the server,

110
00:04:19,103 --> 00:04:21,360
but with an important difference:

111
00:04:21,360 --> 00:04:24,725
the elements can have event handlers attached,

112
00:04:24,725 --> 00:04:27,955
like the "handleClick" function associated

113
00:04:27,955 --> 00:04:30,263
to the button "onClick" event.

114
00:04:30,339 --> 00:04:32,606
So at this point the browser

115
00:04:32,606 --> 00:04:34,386
needs to somehow merge

116
00:04:34,467 --> 00:04:36,917
the elements already displayed on the page

117
00:04:36,917 --> 00:04:40,225
from the initial HTML generated by the server,

118
00:04:40,225 --> 00:04:43,694
with the elements rendered on the client side.

119
00:04:43,694 --> 00:04:47,125
This is what the "hydration" process does.

120
00:04:47,125 --> 00:04:48,500
The result will be

121
00:04:48,500 --> 00:04:52,328
the same HTML elements pre-rendered by the server

122
00:04:52,328 --> 00:04:55,059
but with the addition of event handlers,

123
00:04:55,059 --> 00:04:57,595
and all the JavaScript code associated

124
00:04:57,595 --> 00:04:58,862
with our component.

125
00:04:58,929 --> 00:05:00,715
So at this point we have some

126
00:05:00,715 --> 00:05:02,378
fully-interactive elements,

127
00:05:02,439 --> 00:05:04,487
like a button that can actually do

128
00:05:04,487 --> 00:05:06,535
something when the user clicks it.

