1 00:00:02,250 --> 00:00:08,070 We'll continue working on the app we built in the last course module with our recipes here and with 2 00:00:08,070 --> 00:00:15,070 the filters we could set and so on and there are two things we need to add where we will need Redux. 3 00:00:15,090 --> 00:00:21,870 One is that we actually can mark a recipe as a favorite by clicking that star icon, that this actually 4 00:00:21,870 --> 00:00:27,900 marks this as a favorite and that we for one also change this icon to show whether that already is a 5 00:00:27,900 --> 00:00:28,980 favorite or not 6 00:00:28,980 --> 00:00:35,400 but then more importantly, that we can see that recipe as a favorite here in the favorites tab. And the 7 00:00:35,400 --> 00:00:41,280 other thing where we will need Redux is here in the filters, there when we set a filter and we then 8 00:00:41,280 --> 00:00:49,080 save this, of course this should have an effect on the meals we're loading here in our meals tab in the 9 00:00:49,080 --> 00:00:51,470 list of meals when we select a category. There 10 00:00:51,500 --> 00:00:58,880 this should be reflected, what we set on the filters. So that is what we work on, what we'll need Redux 11 00:00:58,880 --> 00:01:02,300 for and for that, let's install Redux and let's get started with it. 12 00:01:03,350 --> 00:01:07,760 To get started with Redux, I'll quit my expo server here, 13 00:01:07,760 --> 00:01:12,830 the npm start process, I'll quit it temporarily and install a package 14 00:01:12,860 --> 00:01:15,030 and that would be Redux 15 00:01:15,110 --> 00:01:22,460 and in addition to Redux, we also need to install React Redux because that's also required to then 16 00:01:22,460 --> 00:01:23,760 work with Redux. 17 00:01:23,780 --> 00:01:28,700 So both packages need to be installed here and whilst they are installing, we can already get started 18 00:01:28,700 --> 00:01:34,280 working on our code files there a little bit because in this project, I want to add a new folder now 19 00:01:34,280 --> 00:01:35,780 and it's the store folder. 20 00:01:35,780 --> 00:01:40,810 Now you can name this folder whatever you want, it doesn't have to be named store, Redux doesn't care 21 00:01:41,000 --> 00:01:46,970 but this is the folder where I want to manage my Redux setup in because Redux is all about that central 22 00:01:46,970 --> 00:01:48,390 state store. 23 00:01:48,530 --> 00:01:56,150 So here in that store folder, we can now get started with Redux and I won't cover Redux in the greatest 24 00:01:56,150 --> 00:01:57,230 detail here, 25 00:01:57,260 --> 00:02:02,510 I have a complete React and Redux course for that if you want to learn the ins and outs of that, for this course 26 00:02:02,570 --> 00:02:08,450 I actually assume prior React and Redux knowledge and therefore this will only be a brief refresher. 27 00:02:09,890 --> 00:02:14,980 Redux in the end is all about reducers, actions and then building a store based on these reducers 28 00:02:14,980 --> 00:02:16,010 and actions. 29 00:02:16,360 --> 00:02:23,230 Now for that here in that store folder, I'll add an actions folder and I'll add a reducers folder, actually 30 00:02:23,320 --> 00:02:29,320 we'll only have one action and one reducer file in this project but if you had more files than that, having 31 00:02:29,320 --> 00:02:34,180 separate subfolders might be a good idea to keep it organized and that's why I create them here, even 32 00:02:34,180 --> 00:02:39,820 though for this simple app, we wouldn't need that because we won't have that many files. 33 00:02:39,880 --> 00:02:44,230 Let's get started with the reducer. In the reducer folder here, 34 00:02:44,350 --> 00:02:52,630 I'll add my meals.js file and that's the file where I went to manage my meals reducer state updating 35 00:02:52,630 --> 00:02:53,310 logic. 36 00:02:53,410 --> 00:02:58,750 So that's in the end the file where we will write the logic for marking a meal as a favorite and for 37 00:02:58,750 --> 00:03:01,330 managing our filters. 38 00:03:01,430 --> 00:03:04,700 Now a reducer in React is just a function, 39 00:03:04,700 --> 00:03:10,550 So here I will create a function, name it meals reducer, name is totally up to you and this function 40 00:03:10,610 --> 00:03:17,360 will actually receive two arguments - the state, the current state snapshot on which you can build up on 41 00:03:17,360 --> 00:03:22,250 and derive a new state because a reducer in the end will have to return a new state which is then 42 00:03:22,370 --> 00:03:24,860 taken by Redux and stored in its store. 43 00:03:24,860 --> 00:03:30,230 So you get the current, the old state here and you get the action because the reducer function here 44 00:03:30,230 --> 00:03:31,940 is executed by Redux 45 00:03:31,940 --> 00:03:36,710 whenever a new action is dispatched and therefore we get access to the action here so that we can find 46 00:03:36,710 --> 00:03:40,370 out if we need to act and what we need to do. 47 00:03:40,520 --> 00:03:44,960 So inside of this function, in the end then you need to return a new state, in its simplest form 48 00:03:44,960 --> 00:03:49,220 that of course means we return the current state which on the other hand means that this reducer doesn't 49 00:03:49,220 --> 00:03:52,470 do anything useful but we'll change that. 50 00:03:52,650 --> 00:03:58,170 Now when we first execute our app, we also want to set up an initial state which is used initially, so 51 00:03:58,170 --> 00:04:00,000 which initializes our state 52 00:04:00,000 --> 00:04:06,510 when this app launches and for this, I'll add a new initial state constant here which holds a simple 53 00:04:06,510 --> 00:04:14,970 Javascript object and in there, I want to store a list of my meals and then also a list of my filtered 54 00:04:15,120 --> 00:04:22,060 meals because we'll need both - a list of all meals and a list of the meals that fit the filters the user 55 00:04:22,060 --> 00:04:31,130 set and I also want to have my favorite meals here. So three types of meal arrays which I store in 56 00:04:31,130 --> 00:04:31,610 the end 57 00:04:31,670 --> 00:04:34,800 and of course that's just one possible approach you could take here, 58 00:04:34,830 --> 00:04:40,340 we can certainly find other ways of managing our data here but I like this one. 59 00:04:40,590 --> 00:04:53,140 Now what I'll need in this file is my meals dummy data, so I'll import meals from my data folder and 60 00:04:53,140 --> 00:04:59,860 there from the dummy-data.js file and I'll initialize meals here with my meals dummy data array. 61 00:05:00,550 --> 00:05:06,220 Filtered meals also is initialized with that because initially when this app starts, we have no filters 62 00:05:06,330 --> 00:05:11,840 setup. Favorite meals on the other hand initially is an empty array because again when the app starts, we'll 63 00:05:11,840 --> 00:05:13,130 have no favorite meals. 64 00:05:13,130 --> 00:05:18,230 Of course in a real app, you might want to store that state on a server, so that when the user closes 65 00:05:18,230 --> 00:05:21,400 the app and comes back later, you don't start from scratch again 66 00:05:21,470 --> 00:05:23,230 but that's not something we'll do here, 67 00:05:23,240 --> 00:05:28,580 you'll learn how to reach out to a server and save data there and load data from there in separate modules 68 00:05:28,610 --> 00:05:29,440 later in this course, 69 00:05:29,460 --> 00:05:33,040 here we'll keep this simple to focus on Redux. 70 00:05:33,140 --> 00:05:39,170 So this is my initial state, here in this function we can now use a Javascript syntax where we assign 71 00:05:39,230 --> 00:05:44,690 our initial state as a default value for the state argument, which means that when this reducer function 72 00:05:44,690 --> 00:05:51,290 runs and state is undefined which is the case when Redux executes our reducer for the very first time, 73 00:05:51,590 --> 00:05:53,700 we'll get started with that initial state, 74 00:05:53,750 --> 00:05:56,330 so that will then automatically load our initial state 75 00:05:56,330 --> 00:06:02,760 so to say because when Redux gets started and starts up, there will be one initial action dispatched 76 00:06:02,790 --> 00:06:07,910 which is used to run through the reducer once and that will then load our initial state. 77 00:06:07,980 --> 00:06:14,160 So with that, we can work with some initial state which is nice but which on its own doesn't help us 78 00:06:14,160 --> 00:06:16,190 too much. For the moment, 79 00:06:16,200 --> 00:06:17,070 that is it though, 80 00:06:17,250 --> 00:06:23,640 let's now connect this reducer to Redux such that we can actually use our Redux store everywhere in 81 00:06:23,640 --> 00:06:30,860 the app before we then start dispatching actions and do more useful stuff in the reducer. Hence here 82 00:06:30,860 --> 00:06:39,890 for now, I will just export the meals reducer as a default here and now in app.js which is the 83 00:06:39,890 --> 00:06:42,190 file where our entire app starts, 84 00:06:42,230 --> 00:06:47,960 we need to setup our Redux store. For that in here, 85 00:06:48,080 --> 00:06:57,270 we import create store from Redux. 86 00:06:57,510 --> 00:07:02,010 In addition, we'll need to import combine reducers from there. 87 00:07:02,010 --> 00:07:06,090 This allows us to now create a store, we'll just need our reducer, 88 00:07:06,090 --> 00:07:12,610 so here I'll import my meals reducer from and now point at the store folder, 89 00:07:12,610 --> 00:07:15,280 the reducers folder and there, the meals.js 90 00:07:15,330 --> 00:07:26,520 file and now maybe here, we can create our store here by calling create store. Now create store takes 91 00:07:26,640 --> 00:07:31,910 a reducer in the end which you need to pass in. Now of course here, we have a reducer and we could pass this 92 00:07:31,920 --> 00:07:36,780 in but in bigger apps, you might have more than one reducer because you often have reducers for the 93 00:07:36,780 --> 00:07:43,710 different feature areas of your app, one for authentication, one for your products, one for let's say the 94 00:07:43,710 --> 00:07:49,740 support area of your app and you need to merge all these single reducers, these different reducers 95 00:07:49,800 --> 00:07:53,970 into one root reducer and that's what the combined reducers function does, 96 00:07:54,000 --> 00:07:58,800 again here we wouldn't need it because we only have one reducer but to already show you the approach 97 00:07:58,800 --> 00:08:01,060 you could use with multiple reducers as well, 98 00:08:01,140 --> 00:08:07,890 I will use it here as well. So I will have my root reducer here which I create by calling combine reducers, 99 00:08:07,890 --> 00:08:14,460 combined reducers takes a Javascript object where we now map our single reducers, our different 100 00:08:14,460 --> 00:08:16,130 reducers to keys. 101 00:08:16,130 --> 00:08:21,870 So for example here, we could take meals as a key but that name is totally up to you and connect this 102 00:08:22,740 --> 00:08:24,900 to the meals reducer, like this. 103 00:08:24,900 --> 00:08:32,760 What this does is it in the end merges this meal reducer into this root reducer and we'll later be 104 00:08:32,760 --> 00:08:37,380 able to work with the state managed by the meals reducer, 105 00:08:37,380 --> 00:08:43,440 so with this state which is initialized like this, with the help of this meals property, we'll be able 106 00:08:43,440 --> 00:08:44,900 to access this state, 107 00:08:44,910 --> 00:08:49,630 this slice of the state with this property later but you'll see all of that. 108 00:08:49,740 --> 00:08:54,780 So that's our root reducer and now we just have to pass the root reducer to create store, 109 00:08:54,780 --> 00:08:57,900 this gives us a store and now what? 110 00:08:57,900 --> 00:09:03,210 Now this store needs to be provided to our application and for that, we need that 111 00:09:03,240 --> 00:09:06,960 other package which we installed which is React Redux. 112 00:09:07,170 --> 00:09:18,300 From there, we can import the provider component, provider like this. We then wrap provider around our 113 00:09:18,390 --> 00:09:25,200 root app component in the end, so around the topmost component which holds all other components that will 114 00:09:25,200 --> 00:09:30,000 eventually interact with our store and the meals navigator is pretty good for that because that holds 115 00:09:30,060 --> 00:09:35,960 all our screens, so it holds all components that we'll eventually need to dispatch actions or access our 116 00:09:35,960 --> 00:09:36,420 state, 117 00:09:36,480 --> 00:09:44,230 so read from our state. Hence here we wrap the provider component around the meals navigator and now 118 00:09:44,230 --> 00:09:50,440 provider takes one important property, one prop which you have to pass and that's the store prop 119 00:09:50,680 --> 00:09:54,590 and of course there, as a value we pass our store here. 120 00:09:54,640 --> 00:10:01,660 So this constant store which holds the created store is passed to the store prop provider and behind 121 00:10:01,660 --> 00:10:07,990 the scenes, this gives us everything we need to now interact with Redux, with the Redux store in any component, 122 00:10:08,050 --> 00:10:11,520 any screen or any other component in our application. 123 00:10:13,360 --> 00:10:18,630 Now let me restart this with npm start and for the moment, this won't make a big difference but our app 124 00:10:18,630 --> 00:10:21,430 should certainly still work, so it shouldn't crash because of that, so 125 00:10:21,430 --> 00:10:29,140 let's just verify that this is the case and let's reload here, we're pressing r twice on Android and command 126 00:10:29,170 --> 00:10:38,370 r on iOS and let's see where that still loads as it should, yes that's looking good here on iOS and 127 00:10:38,730 --> 00:10:44,860 I'm pretty confident that it will also load just fine on Android, yes that's working too. 128 00:10:44,890 --> 00:10:46,890 So now Redux is set up, 129 00:10:46,900 --> 00:10:49,990 our store is initialized but we're not using it. 130 00:10:49,990 --> 00:10:54,520 So as a next step, let's make sure we use our store before we then take care about actions and doing 131 00:10:54,520 --> 00:10:56,200 some real work in the reducer.