1 00:00:02,220 --> 00:00:06,510 Let's make sure we can go to the product detail screen, this screen here 2 00:00:06,510 --> 00:00:09,870 and for that first of all in the product detail screen component, 3 00:00:09,870 --> 00:00:13,170 well I'll set up a component by importing React from 4 00:00:13,170 --> 00:00:15,590 React. Then 5 00:00:15,620 --> 00:00:21,150 in there, we probably also need some things from React Native, 6 00:00:21,210 --> 00:00:26,940 for example it can't really hurt to have a view and a text in here and also a stylesheet 7 00:00:27,150 --> 00:00:32,880 and also the image component, by the way the order of these imports here of course does not matter. 8 00:00:32,890 --> 00:00:38,430 I also want to have a button in there because I want to have an add to cart button in here as well and 9 00:00:38,610 --> 00:00:47,250 actually also a scroll view because this detail page could have a very long product description or could 10 00:00:47,250 --> 00:00:52,440 be viewed on a very small device and therefore, it should definitely be scrollable so that we can always see all 11 00:00:52,440 --> 00:00:55,950 the content. With that 12 00:00:55,950 --> 00:01:03,940 here, I'll add my product detail screen component, again a functional component where we receive props, 13 00:01:04,210 --> 00:01:10,420 I'll set up my stylesheet here with stylesheet.create and store it in a styles constant 14 00:01:10,420 --> 00:01:17,440 and of course export the product detail screen as a default. With that, 15 00:01:17,500 --> 00:01:26,340 let's start simple and return a view here with a text where we say the product detail screen which is 16 00:01:26,340 --> 00:01:29,570 just there so that we can see that we successfully navigated there 17 00:01:29,610 --> 00:01:34,500 and so that we can actually use this because we have to return jsx to have a valid component because 18 00:01:34,500 --> 00:01:39,750 the first thing I want to do is adjust the navigation and for that in the ShopNavigator.js file in the 19 00:01:39,750 --> 00:01:42,290 navigation folder, 20 00:01:42,420 --> 00:01:51,020 we can import the product detail screen here from our screens folder, the shop folder and there the product 21 00:01:51,020 --> 00:01:51,760 detail screen, 22 00:01:51,770 --> 00:01:58,750 so that's the file we just worked in of course and map this to an identifier here, I'll name it product 23 00:01:58,750 --> 00:01:59,830 detail here. 24 00:01:59,830 --> 00:02:03,640 These keys as you learned in the navigation section are always up to you, 25 00:02:03,640 --> 00:02:06,070 so now we mapped this screen. 26 00:02:06,220 --> 00:02:09,570 This will be our starting screen because this is the first key-value pair, 27 00:02:09,580 --> 00:02:14,170 this is a screen we can go to though, we can navigate to and to go there, 28 00:02:14,170 --> 00:02:20,440 we need to go to our products overview screen and when we click on view detail, this is in the end the signal 29 00:02:20,440 --> 00:02:24,700 that we want to go to that product detail screen. 30 00:02:24,700 --> 00:02:32,140 So here in this function, we can call props navigation navigate, this navigate function which you learned 31 00:02:32,140 --> 00:02:35,260 about in the navigation section and then there, 32 00:02:35,320 --> 00:02:40,170 I showed you one syntax where you pass in a Javascript object where you set up a route 33 00:02:40,180 --> 00:02:46,340 name, that could be product detail and that will take you to the screen. 34 00:02:46,340 --> 00:02:47,920 So now we save this and 35 00:02:47,930 --> 00:02:55,430 we click on view details, indeed we go to the product detail screen. Now as an annotation in the navigation 36 00:02:55,430 --> 00:02:55,980 section, 37 00:02:55,990 --> 00:03:02,270 I also showed you of course that the alternative syntax to that is that you just pass in the screen 38 00:03:02,270 --> 00:03:03,970 name as a first argument to navigate, 39 00:03:03,980 --> 00:03:09,080 so you can do that as well and it will just work as well. If we also test this on Android, 40 00:03:09,080 --> 00:03:11,750 this is how we can go there. 41 00:03:11,940 --> 00:03:19,410 Now obviously, the goal is not just to go there but to also forward our data or our ID of the product 42 00:03:19,410 --> 00:03:25,200 at least so that we can load the product data inside of the component. Hence as a second argument here, 43 00:03:25,710 --> 00:03:30,380 I pass in a Javascript object which will be my params for this navigation action 44 00:03:30,510 --> 00:03:36,060 and there you can have any key-value pairs you want, I'll add a product ID field here, again this name 45 00:03:36,090 --> 00:03:42,120 is totally up to you though and this will be itemData.item.id because itemData.item 46 00:03:42,120 --> 00:03:48,480 points at a single product which has the look we set up here in models and this has ID prop, so 47 00:03:48,480 --> 00:03:55,350 of course we can access this here and forward it. With that, in the product detail screen, we can extract 48 00:03:55,380 --> 00:04:01,410 this of course, that's also something you learned earlier and which you can just practice here. 49 00:04:01,410 --> 00:04:11,880 We can get our product ID here by simply calling props navigation get param product ID and this 50 00:04:11,880 --> 00:04:17,160 will extract our product ID from the parameters we received. 51 00:04:17,180 --> 00:04:22,580 Now we can use that ID to get our product and of course our products are stored in Redux. 52 00:04:22,640 --> 00:04:29,510 So in the end we need to import use selector here from React Redux, so that we can use it to select a 53 00:04:29,510 --> 00:04:30,830 single product, 54 00:04:30,830 --> 00:04:37,220 our let's say selected product, this constant name is of course also up to you, is now selected with the 55 00:04:37,220 --> 00:04:43,010 help of use selector which receives our state, our Redux state and then we can drill into the products 56 00:04:43,070 --> 00:04:51,420 slice, again that slice name is what you use here in combined reducers products in my case and there 57 00:04:51,470 --> 00:04:54,650 we can get an access to all available products 58 00:04:54,680 --> 00:04:59,230 but of course here I don't want to load all available products but instead, I can use the find method 59 00:04:59,240 --> 00:05:06,650 to find a single product with that function that I pass to find which runs on every item in the array where 60 00:05:06,650 --> 00:05:12,560 we get the product where this function returns true and it should return true if the ID of the product 61 00:05:12,560 --> 00:05:18,290 I'm looking at is equal to the product ID I extracted from the route parameters. 62 00:05:18,290 --> 00:05:23,470 This is how we select a single product and this single product can then be used here, 63 00:05:23,470 --> 00:05:32,930 so here we could output selectedProduct.title for example. If we now save that and we view the 64 00:05:32,930 --> 00:05:33,860 details, 65 00:05:33,860 --> 00:05:37,970 indeed here I see red shirt, if I do that for the blue carpet, I see blue carpet here, 66 00:05:37,970 --> 00:05:41,590 so that's working. It would be nice to see that in the header as well 67 00:05:41,720 --> 00:05:43,110 and there are two options, 68 00:05:43,280 --> 00:05:53,810 we could now use props.navigation set param here and also wrap this in the use 69 00:05:53,810 --> 00:05:55,030 effect call of course, 70 00:05:55,030 --> 00:06:01,880 that would be better to set our title with set param and use it here in the navigation options which 71 00:06:01,880 --> 00:06:07,690 we have to add to products detail to extract it or actually a bit easier, 72 00:06:07,700 --> 00:06:12,710 we go to the product overview which is where we go to that page and besides passing the product ID, we 73 00:06:12,710 --> 00:06:17,000 also pass the product title because here we have that easily available and 74 00:06:17,000 --> 00:06:20,120 we get it with the help of itemData.item.title. 75 00:06:20,150 --> 00:06:25,400 Now we set this param as well and this makes it super easy to extract it in the product detail screen, 76 00:06:25,820 --> 00:06:31,490 there in the navigation options, we can just now add product detail screen navigation 77 00:06:33,930 --> 00:06:40,440 options and this is now the functional form because we need to extract this in a dynamic way from our 78 00:06:40,440 --> 00:06:41,730 route params. 06:41.730 -- 06:48.390 So here we get this nav data object which also has a navigation prop, we need to return our Javascript 79 00:06:48,420 --> 00:06:55,590 object, our navigation options config object here, this should be options of course and in there, 80 00:06:55,620 --> 00:07:07,770 we can set the header title to navData.navigation.getParam product title or whatever you chose 81 00:07:07,830 --> 00:07:11,170 as an identifier for this. 82 00:07:11,190 --> 00:07:17,060 So here I'm using product title because in the product overview screen, I'm setting this to product title. 83 00:07:19,600 --> 00:07:25,600 With that, we're setting this header, let's see whether that works, if we try to go to that screen, 84 00:07:25,900 --> 00:07:27,130 that's looking good, 85 00:07:27,130 --> 00:07:34,560 now we also see the the title of the product here in the header. That is working. 86 00:07:34,560 --> 00:07:39,420 Now I mentioned earlier that we should not just be able to go there by pressing view details but maybe 87 00:07:39,420 --> 00:07:41,840 also by pressing the product in general 88 00:07:42,170 --> 00:07:47,930 and for that, we can go to the product item and there of course, we have the view detail button 89 00:07:47,930 --> 00:07:51,310 but now we can wrap the entire item of course in a touchable 90 00:07:51,440 --> 00:08:01,000 and there we can use touchable opacity and wrap this entire item with touchable opacity, 91 00:08:01,160 --> 00:08:04,430 so wrap this around our entire view here, 92 00:08:04,430 --> 00:08:09,110 these buttons still will be triggered standalone but now we can also press anywhere else and there 93 00:08:09,130 --> 00:08:09,900 onPress, 94 00:08:09,920 --> 00:08:15,710 I now also want to trigger the same, the view details button does, I want to trigger the function we receive 95 00:08:15,740 --> 00:08:22,730 on on view detail, so I will simply forward this to on view detail. And that with that simple change, we 96 00:08:22,730 --> 00:08:28,970 can press anywhere on this item to be taken to the detail screen, also on Android where this however 97 00:08:28,970 --> 00:08:34,080 looks a bit ugly and in general, it would be nice to have this ripple effect there. 98 00:08:34,220 --> 00:08:36,980 Now you also learned how you can implement this, 99 00:08:37,070 --> 00:08:44,760 we need to import touchable native feedback for that and the platform API, so this platform object 100 00:08:44,760 --> 00:08:52,980 and now here in product item, we can set up our touchable component here or whatever you want to name 101 00:08:52,980 --> 00:08:58,650 it, should have a capital character though so that we can use it as a jsx element and this by default 102 00:08:58,660 --> 00:09:00,710 points at touchable opacity let's say 103 00:09:00,720 --> 00:09:10,050 but if platform OS is equal to Android and the platform version is greater or equal than 21 which 104 00:09:10,050 --> 00:09:13,240 is the Android version we need to support the ripple effect, 105 00:09:13,440 --> 00:09:22,410 we can set touchable cmp equal to touchable native feedback and now we can replace touchable opacity 106 00:09:22,410 --> 00:09:23,100 down there 107 00:09:24,210 --> 00:09:28,120 with touchable cmp 108 00:09:28,220 --> 00:09:34,040 so with that variable which holds two different kinds of components depending on where it's running 109 00:09:34,850 --> 00:09:40,330 and now if we do this, we still have that opacity effect here but we have a ripple effect on Android. 110 00:09:40,340 --> 00:09:48,980 However only down there, not on the image and also not respecting our rounded corners as you can maybe 111 00:09:48,980 --> 00:09:49,930 see. 112 00:09:50,390 --> 00:09:52,770 Now to fix the issue that is not on the image, 113 00:09:52,850 --> 00:09:56,500 all we have to do is we have to change some configuration there, 114 00:09:56,690 --> 00:10:01,990 we just have to add the use foreground prop here. 115 00:10:02,050 --> 00:10:07,570 Now on touchable opacity, this will have no effect but on touchable native feedback, this makes sure that 116 00:10:07,570 --> 00:10:12,850 the ripple effect does not apply to the background but actually to the foreground which means 117 00:10:12,910 --> 00:10:19,180 also to elements that are placed on top of our touchable or inside of our touchable component. 118 00:10:19,180 --> 00:10:25,360 So therefore now, this is also on the image and to respect the corners, the rounded corners, I'll actually 119 00:10:25,360 --> 00:10:27,560 do this a bit differently, 120 00:10:27,670 --> 00:10:33,840 I'll add a touchable component inside of my surrounding view instead of outside, like that 121 00:10:35,550 --> 00:10:42,860 and now here I'll add overflow hidden on that product style which is on that view which is now around 122 00:10:42,870 --> 00:10:48,260 my touchable component. With that however, my shadow is lost as you can tell 123 00:10:48,260 --> 00:10:55,710 and here I now even get an error that I need a single React child. Therefore let's actually tweak this 124 00:10:55,710 --> 00:11:01,590 a little bit and let's add an extra view in here, an extra view that wraps everything, my entire touchable 125 00:11:01,590 --> 00:11:11,370 component inside of that outer view and on that extra view, I'll add a style of styles touchable or whatever 126 00:11:11,370 --> 00:11:19,090 you want to name it and this touchable style is now added down here in my stylesheet. 127 00:11:19,180 --> 00:11:21,260 This now gets the overflow 128 00:11:21,370 --> 00:11:28,090 hidden prop, so we add this here and this now also receives the same border radius we have on the 129 00:11:28,090 --> 00:11:36,000 entire cart, so border radius of 10 here and this will now make sure that we keep our shadow, so that still 130 00:11:36,000 --> 00:11:41,220 works because overflow hidden would have cropped this and now to get rid of that other error here as 131 00:11:41,220 --> 00:11:47,230 well, we can simply wrap yet another view around all the content inside of touchable component so that 132 00:11:47,240 --> 00:11:52,890 we'll fulfill this criteria of having only one child item in touchable component 133 00:11:52,890 --> 00:11:58,620 and now with that, we have the same behavior as before on iOS. To cart by the way does not trigger this 134 00:11:58,620 --> 00:12:01,940 details navigation which is good and on Android, 135 00:12:02,070 --> 00:12:06,780 we now also have that ripple effect which respects our rounded corners which takes us to the detail view 136 00:12:07,050 --> 00:12:12,270 and to cart also does not do that which it shouldn't. 137 00:12:12,270 --> 00:12:15,050 So with that, now we have the navigation we need, 138 00:12:15,060 --> 00:12:17,210 we have the look we need here. 139 00:12:17,490 --> 00:12:23,490 Now we can go to the detail page and we should now maybe make sure that this detail page also looks the way 140 00:12:23,490 --> 00:12:24,020 it should look.