1
00:00:03,000 --> 00:00:05,106
We know from the previous video that

2
00:00:05,106 --> 00:00:08,578
Client Components are hydrated in the browser.

3
00:00:08,578 --> 00:00:10,006
When we load the page,

4
00:00:10,378 --> 00:00:13,554
the ShareLinkButton is first rendered

5
00:00:13,554 --> 00:00:15,443
as HTML on the server,

6
00:00:15,528 --> 00:00:17,935
and then rendered again in the browser,

7
00:00:17,935 --> 00:00:21,225
this time adding any interactive functionality.

8
00:00:21,225 --> 00:00:24,368
You may wonder why we need to send to the browser

9
00:00:24,368 --> 00:00:27,560
the full JavaScript code for this component.

10
00:00:27,560 --> 00:00:30,843
Since all we do when the user clicks the button

11
00:00:30,843 --> 00:00:33,896
is execute the "handleClick" function,

12
00:00:33,896 --> 00:00:36,537
in theory we could send to the browser

13
00:00:36,537 --> 00:00:38,761
only the code for that function.

14
00:00:38,830 --> 00:00:41,215
Why does React need to re-render

15
00:00:41,215 --> 00:00:42,706
the whole component?

16
00:00:42,780 --> 00:00:45,154
The reason is that most of the time

17
00:00:45,154 --> 00:00:48,268
we'll also want to do other things in a component,

18
00:00:48,268 --> 00:00:51,015
like updating the user interface.

19
00:00:51,015 --> 00:00:53,272
For example, when the user clicks

20
00:00:53,272 --> 00:00:54,914
the "Share link" button,

21
00:00:54,983 --> 00:00:57,136
we'll want to display a message,

22
00:00:57,136 --> 00:00:58,549
telling the user that

23
00:00:58,617 --> 00:01:01,867
the link was in fact copied to the clipboard.

24
00:01:01,867 --> 00:01:04,949
To do that, we'll also need to keep some state,

25
00:01:04,949 --> 00:01:09,009
to know when to display the "link copied" message.

26
00:01:09,009 --> 00:01:12,108
In React, we can create a state variable

27
00:01:12,108 --> 00:01:14,045
with the "useState" hook.

28
00:01:14,122 --> 00:01:15,856
It will return an array,

29
00:01:15,856 --> 00:01:18,874
where the first element is our state variable,

30
00:01:18,874 --> 00:01:20,449
let's call it "clicked",

31
00:01:20,515 --> 00:01:22,925
and the second element is a function

32
00:01:22,925 --> 00:01:26,125
that we can use to update the variable value.

33
00:01:26,125 --> 00:01:29,436
We'll get this array by calling "useState",

34
00:01:29,436 --> 00:01:32,248
that we can import from the "react" module.

35
00:01:32,248 --> 00:01:33,998
We can pass an initial value

36
00:01:33,998 --> 00:01:35,436
for our state variable,

37
00:01:35,499 --> 00:01:38,570
in this case we want "clicked" to be false.

38
00:01:38,570 --> 00:01:41,809
Now we can use this variable to decide

39
00:01:41,809 --> 00:01:45,166
what text to display as the button label.

40
00:01:45,166 --> 00:01:47,287
If "clicked" is true then we

41
00:01:47,287 --> 00:01:49,030
can say "Link copied!",

42
00:01:49,105 --> 00:01:51,295
while if it's false we'll show

43
00:01:51,295 --> 00:01:52,974
"Share link" as before.

44
00:01:53,047 --> 00:01:56,160
Let me log this "clicked" variable to the console,

45
00:01:56,367 --> 00:01:58,445
so you can see its value whenever

46
00:01:58,445 --> 00:02:00,145
this component is rendered.

47
00:02:00,208 --> 00:02:02,593
I'll show you the server logs as well,

48
00:02:02,948 --> 00:02:04,981
and go and reload the page.

49
00:02:04,981 --> 00:02:08,160
You can see that, initially, "clicked" is false,

50
00:02:08,160 --> 00:02:11,668
because that's the value we passed to "useState",

51
00:02:11,668 --> 00:02:13,673
and it's the same both on the

52
00:02:13,673 --> 00:02:15,470
server and in the browser.

53
00:02:15,539 --> 00:02:18,138
Now, we'll want to change that value

54
00:02:18,138 --> 00:02:20,478
when the user clicks the button,

55
00:02:20,478 --> 00:02:21,940
so in "handleClick".

56
00:02:22,013 --> 00:02:25,063
Here we can call the "setClicked" function,

57
00:02:25,063 --> 00:02:28,797
that was the second element returned by useState,

58
00:02:28,797 --> 00:02:31,320
passing true as the new value,

59
00:02:31,320 --> 00:02:34,194
since the user just clicked the button.

60
00:02:34,194 --> 00:02:37,194
This will cause our component to re-render

61
00:02:37,194 --> 00:02:39,409
with "clicked" set to true,

62
00:02:39,409 --> 00:02:42,038
which means the button text should

63
00:02:42,038 --> 00:02:43,971
change to "Link copied!".

64
00:02:44,049 --> 00:02:47,918
But we don't want it to say "Link copied" forever.

65
00:02:47,918 --> 00:02:51,754
Let's use "setTimeout" to reset it after a while.

66
00:02:51,754 --> 00:02:54,580
We can set "clicked" back to false,

67
00:02:54,834 --> 00:02:57,982
after say 1500 milliseconds,

68
00:02:57,982 --> 00:03:00,445
that means one and a half seconds.

69
00:03:00,445 --> 00:03:02,505
Let's see how it works now, if

70
00:03:02,505 --> 00:03:04,427
we start from scratch again.

71
00:03:04,496 --> 00:03:07,152
Initially, "clicked" is always false.

72
00:03:07,152 --> 00:03:09,292
But if we go and click the button,

73
00:03:09,292 --> 00:03:12,140
the text changes to "Link copied!",

74
00:03:12,140 --> 00:03:14,034
but only for a short while,

75
00:03:14,034 --> 00:03:16,526
then it goes back to "Share link".

76
00:03:16,526 --> 00:03:18,497
In the console, you can see that

77
00:03:18,497 --> 00:03:20,641
right after we clicked the button

78
00:03:20,641 --> 00:03:24,408
the component re-rendered with "clicked" as true,

79
00:03:24,408 --> 00:03:26,365
and later, once the timeout

80
00:03:26,365 --> 00:03:28,032
function was triggered,

81
00:03:28,104 --> 00:03:31,779
it rendered again, with "clicked" back to false.

82
00:03:31,779 --> 00:03:33,736
Of course, the component only

83
00:03:33,736 --> 00:03:35,557
re-rendered in the browser,

84
00:03:35,624 --> 00:03:38,025
not on the server, where it's only

85
00:03:38,025 --> 00:03:40,426
used to generate the initial HTML.

86
00:03:40,496 --> 00:03:42,840
Anyway, we're now briefly showing

87
00:03:42,840 --> 00:03:44,828
"Link clicked!" to the user,

88
00:03:44,899 --> 00:03:46,688
so they know that clicking

89
00:03:46,688 --> 00:03:48,408
the button did something.

90
00:03:48,476 --> 00:03:51,407
At this point, all that's left to do is

91
00:03:51,407 --> 00:03:54,321
actually copy the link to the clipboard,

92
00:03:54,321 --> 00:03:57,130
that is the whole point of this button.

93
00:03:57,130 --> 00:03:59,324
The "navigator" global object

94
00:03:59,324 --> 00:04:01,366
has a "clipboard" property,

95
00:04:01,442 --> 00:04:04,986
that we can use to access the system clipboard.

96
00:04:04,986 --> 00:04:07,504
To copy something into it we can

97
00:04:07,504 --> 00:04:09,708
call the "writeText" method.

98
00:04:09,787 --> 00:04:12,821
Now, we want to pass the page URL,

99
00:04:12,821 --> 00:04:15,087
that will be the same one visible

100
00:04:15,087 --> 00:04:16,942
in the browser address bar.

101
00:04:17,010 --> 00:04:19,565
We can get that value in JavaScript

102
00:04:19,565 --> 00:04:22,512
by using the "window.location" object.

103
00:04:22,766 --> 00:04:25,985
Its "href" property will be the URL.

104
00:04:25,985 --> 00:04:28,852
Ok. Let's save, and see if this works.

105
00:04:28,852 --> 00:04:32,318
If we click this button, it says "Link copied!".

106
00:04:32,318 --> 00:04:35,363
What I'll do is open a new text file

107
00:04:35,363 --> 00:04:37,444
and press Command+V to paste

108
00:04:37,444 --> 00:04:39,228
what's in the clipboard.

109
00:04:39,302 --> 00:04:42,509
You can see that it is in fact the right URL.

110
00:04:42,509 --> 00:04:45,110
Let's test it with a different review,

111
00:04:45,110 --> 00:04:47,552
like "Stardew Valley" for example.

112
00:04:47,710 --> 00:04:49,637
And if I press Command+V

113
00:04:49,637 --> 00:04:52,695
it copied the URL for that other page.

114
00:04:52,695 --> 00:04:56,337
Good. Our "Share link" button is fully working.

115
00:04:56,337 --> 00:04:58,782
And this is a simple example of

116
00:04:58,782 --> 00:05:00,833
interactive functionality,

117
00:05:00,912 --> 00:05:03,941
that only works in Client Components.

