1
00:00:00,000 --> 00:00:03,000
Now, to show a preview of the picked image,

2
00:00:03,000 --> 00:00:08,000
we need to handle the event that an image was picked

3
00:00:08,000 --> 00:00:13,000
and then store some state so that we can update this UI

4
00:00:13,000 --> 00:00:15,000
and show a preview as soon as we have an image.

5
00:00:17,000 --> 00:00:20,000
So we need some state here in this component,

6
00:00:20,000 --> 00:00:23,000
and therefore, we need to use state hook.

7
00:00:23,000 --> 00:00:25,000
This would require us

8
00:00:25,000 --> 00:00:28,000
to turn this component into a client component,

9
00:00:28,000 --> 00:00:31,000
but we already did this here, so no changes are needed.

10
00:00:33,000 --> 00:00:34,000
Now here with this state,

11
00:00:34,000 --> 00:00:37,000
I then wanna manage the picked image,

12
00:00:37,000 --> 00:00:39,000
so I'll name this picked image

13
00:00:39,000 --> 00:00:43,000
and have a set picked image state updating function.

14
00:00:44,000 --> 00:00:49,000
And now we need a second event handler function here

15
00:00:49,000 --> 00:00:53,000
that could be called handle image change,

16
00:00:53,000 --> 00:00:54,000
which should be triggered

17
00:00:54,000 --> 00:00:58,000
whenever this input here has a new value,

18
00:00:58,000 --> 00:01:01,000
so whenever the change event on that input is emitted.

19
00:01:03,000 --> 00:01:06,000
And therefore, we should add the on change prop here

20
00:01:06,000 --> 00:01:09,000
and set handle image change as a value.

21
00:01:12,000 --> 00:01:14,000
Now, here in handle image change,

22
00:01:14,000 --> 00:01:17,000
we'll then automatically get an event object,

23
00:01:17,000 --> 00:01:18,000
as you always do

24
00:01:18,000 --> 00:01:22,000
for those event handling functions in React,

25
00:01:22,000 --> 00:01:24,000
and we can use this event object

26
00:01:24,000 --> 00:01:26,000
to get hold of that picked image.

27
00:01:28,000 --> 00:01:30,000
We can get hold of that picked file

28
00:01:30,000 --> 00:01:33,000
by using event.target.files

29
00:01:33,000 --> 00:01:35,000
and then accessing the first file.

30
00:01:37,000 --> 00:01:39,000
This file property will exist

31
00:01:39,000 --> 00:01:43,000
because the target of this event is this input,

32
00:01:43,000 --> 00:01:46,000
and this file input object, under the hood,

33
00:01:46,000 --> 00:01:49,000
will have such a files property.

34
00:01:49,000 --> 00:01:51,000
That will be an array of all the files

35
00:01:51,000 --> 00:01:52,000
that have been picked,

36
00:01:52,000 --> 00:01:56,000
but here, it'll only be one file that can be picked.

37
00:01:56,000 --> 00:01:59,000
and therefore. I'll just access that first file.

38
00:01:59,000 --> 00:02:02,000
You could allow the user to pick multiple files

39
00:02:02,000 --> 00:02:06,000
by adding the multiple prop here to this file input,

40
00:02:06,000 --> 00:02:09,000
but since we don't have that here and don't want it here,

41
00:02:09,000 --> 00:02:12,000
it'll only be one file that we can access.

42
00:02:15,000 --> 00:02:17,000
Now, it's possible that the user actually

43
00:02:17,000 --> 00:02:20,000
did not pick a file for some reason,

44
00:02:20,000 --> 00:02:24,000
so I'll check if the file is undefined, if we got no file,

45
00:02:24,000 --> 00:02:27,000
and in that case, I'll just return and not continue.

46
00:02:27,000 --> 00:02:28,000
(paper crumpling)

47
00:02:28,000 --> 00:02:30,000
But if we make it past this if check,

48
00:02:30,000 --> 00:02:33,000
we know that some file has been selected.

49
00:02:34,000 --> 00:02:37,000
Now, in order to show it as a preview here,

50
00:02:37,000 --> 00:02:41,000
I now want to convert it into a so-called data URL,

51
00:02:41,000 --> 00:02:44,000
which is simply a value that can be used as an input

52
00:02:44,000 --> 00:02:46,000
for an image element,

53
00:02:46,000 --> 00:02:50,000
so that can be used as a source for an image element.

54
00:02:51,000 --> 00:02:54,000
And we can generate such a data URL

55
00:02:54,000 --> 00:02:58,000
with help of a class built into JavaScript,

56
00:02:58,000 --> 00:03:00,000
the file reader class.

57
00:03:01,000 --> 00:03:04,000
We can construct such a file reader

58
00:03:04,000 --> 00:03:06,000
and then do what its name implies.

59
00:03:06,000 --> 00:03:08,000
We can read our file,

60
00:03:09,000 --> 00:03:14,000
and we can simply call file reader read as data URL

61
00:03:14,000 --> 00:03:17,000
and pass that file to that method.

62
00:03:19,000 --> 00:03:22,000
Now, this method works in a bit of a strange way,

63
00:03:22,000 --> 00:03:25,000
because it doesn't actually return anything,

64
00:03:25,000 --> 00:03:28,000
not a promise, not the read file,

65
00:03:28,000 --> 00:03:31,000
and it also doesn't take a callback.

66
00:03:31,000 --> 00:03:35,000
Instead, we get hold of that data URL that's being generated

67
00:03:35,000 --> 00:03:39,000
by assigning a value to the on load property

68
00:03:39,000 --> 00:03:42,000
of this file reader object.

69
00:03:43,000 --> 00:03:46,000
So we store a function as a value in on load,

70
00:03:46,000 --> 00:03:49,000
and this function will then be triggered by the file reader

71
00:03:49,000 --> 00:03:51,000
once this method here,

72
00:03:51,000 --> 00:03:54,000
this read as data URL method, is done,

73
00:03:55,000 --> 00:04:00,000
But here, we then won't get the generated URL as an input.

74
00:04:00,000 --> 00:04:05,000
Instead, we can access it by accessing fileReader.result,

75
00:04:07,000 --> 00:04:10,000
and that will then be that generated URL.

76
00:04:11,000 --> 00:04:14,000
And that's what I then wanna store in my state.

77
00:04:14,000 --> 00:04:18,000
So I will set my picked image to the result

78
00:04:18,000 --> 00:04:21,000
of accessing fileReader.result

79
00:04:21,000 --> 00:04:23,000
inside of this on load function.

80
00:04:26,000 --> 00:04:29,000
Well, and with that, we can then use this picked image state

81
00:04:29,000 --> 00:04:30,000
to show a preview.

82
00:04:30,000 --> 00:04:33,000
So down here, in this controls div,

83
00:04:33,000 --> 00:04:38,000
I'll add another div with a class name of preview,

84
00:04:40,000 --> 00:04:42,000
and in that div, I now wanna check

85
00:04:42,000 --> 00:04:45,000
if we don't have a picked image,

86
00:04:45,000 --> 00:04:48,000
in which case I'll simply output a paragraph

87
00:04:48,000 --> 00:04:53,000
where I say "No image picked yet" or something like that.

88
00:04:54,000 --> 00:04:59,000
But if we do have a picked image, I wanna show that image.

89
00:04:59,000 --> 00:05:03,000
And for that, I'll use the image component provided by next,

90
00:05:03,000 --> 00:05:07,000
so you should import that from next image,

91
00:05:07,000 --> 00:05:10,000
and then here on that image,

92
00:05:10,000 --> 00:05:15,000
I'll set the source to my picked image, so to that data URL,

93
00:05:15,000 --> 00:05:20,000
and the alt text to "The image selected by the user,"

94
00:05:22,000 --> 00:05:24,000
and I'll add that fill prop

95
00:05:24,000 --> 00:05:25,000
because I don't know the dimensions

96
00:05:25,000 --> 00:05:28,000
of that image in advance.

97
00:05:30,000 --> 00:05:33,000
And that should then be all.

98
00:05:33,000 --> 00:05:34,000
With that, we should have

99
00:05:34,000 --> 00:05:37,000
that finished image picker component,

100
00:05:37,000 --> 00:05:38,000
and we can now take a look at it.

101
00:05:39,000 --> 00:05:43,000
Here in this application, I now got this preview area,

102
00:05:43,000 --> 00:05:46,000
and if I now click this button, the file picker opens up,

103
00:05:46,000 --> 00:05:50,000
and if I pick an image, I can see that preview here.

104
00:05:50,000 --> 00:05:52,000
So that is working.

105
00:05:52,000 --> 00:05:55,000
And with that, we're now finally ready

106
00:05:55,000 --> 00:05:58,000
to also work on the submission of this form.

