Coding

ReactJS / Redux Tutorial – #9 A better Project Structure

  • 00:00:00 we're on a good way here and we already
  • 00:00:03 made the split between components and
  • 00:00:06 containers though there still is one
  • 00:00:09 problem our application would quickly
  • 00:00:12 get pretty complex to manage or at least
  • 00:00:15 unreadable if it grew more complex
  • 00:00:18 because all the redox code is handled in
  • 00:00:21 the index dot JSON isn't it typically
  • 00:00:28 you would split this up you would create
  • 00:00:31 a new folder in your app folder named
  • 00:00:33 reducers and you might guess what this
  • 00:00:36 folder holds you would also create a new
  • 00:00:40 folder called actions so that's the
  • 00:00:43 typical split you have and then you also
  • 00:00:46 create another file called storage
  • 00:00:49 sheäôs which holds your store so let's
  • 00:00:52 populate them with live step by step
  • 00:00:55 what does the storage JS file do well if
  • 00:01:00 we go to the index chess file it of
  • 00:01:02 course holds our store this one here I
  • 00:01:06 will copy my store or cat it inserted
  • 00:01:11 here but I will not set this to be a
  • 00:01:14 constant its but instead I will set this
  • 00:01:16 to be my default export so the acting
  • 00:01:20 this file exports the store created here
  • 00:01:23 I also since I use logger here need to
  • 00:01:28 import logger from readex logger of
  • 00:01:34 course you may get rid of it entirely if
  • 00:01:35 you don't want the log messages and you
  • 00:01:37 should get rid of it for your production
  • 00:01:39 application of course in order to set up
  • 00:01:43 a store here we also need to import some
  • 00:01:46 things from readex namely the same
  • 00:01:49 things we used in the index.js file
  • 00:01:51 before so that's create store combine
  • 00:01:54 reducers and apply Milla where we also
  • 00:01:58 get the problem that these reducers are
  • 00:02:00 not in the same file so this will not
  • 00:02:02 work for now but I'll come back to this
  • 00:02:05 soon in the index dot JS file I'll get
  • 00:02:08 rid of my own logger here I'll get rid
  • 00:02:11 of the subscription and then I want
  • 00:02:14 creating you reducer files here I'll
  • 00:02:16 create a new reducer file here which
  • 00:02:19 I'll call Mafra user KS and then the
  • 00:02:23 number one which will name user read
  • 00:02:26 user dot j s now the mod producer file
  • 00:02:29 will of course hold my math reducer
  • 00:02:33 which I'll cut and copy into here and
  • 00:02:35 the user reducer well what will this
  • 00:02:38 file hold the user reducer of course now
  • 00:02:41 that should be a constant it should be a
  • 00:02:44 default export and the same is true for
  • 00:02:47 my mofford user your export my index
  • 00:02:53 chess fall its get it getting pretty
  • 00:02:55 lean here isn't it can get rid of all
  • 00:02:58 the imports they don't need anymore
  • 00:03:00 I of course still render my app here I
  • 00:03:04 still hook it up with the provider
  • 00:03:06 component so that is how my index.js
  • 00:03:09 file will look like in the store chess
  • 00:03:12 file and now I need to import my
  • 00:03:14 reducers so I need to import that from
  • 00:03:18 RIT users and then MAF reducer and of
  • 00:03:23 course user read user and what do I want
  • 00:03:26 to import well I could just name this
  • 00:03:28 math and user which allows me to again
  • 00:03:32 use this shorter way of setting this up
  • 00:03:35 like so so now I'm setting up all the
  • 00:03:39 reducers if we have a look at the
  • 00:03:40 application you see it's not running we
  • 00:03:44 get the error that store is not defined
  • 00:03:47 which makes perfect sense because in the
  • 00:03:50 index chest file where I need to pass
  • 00:03:51 store to provider I don't have my store
  • 00:03:54 so I need to import that and to import
  • 00:03:58 it I'm exporting it here as a default
  • 00:04:01 and you store the chair's file so here
  • 00:04:03 I'm importing it from store though with
  • 00:04:07 dot slash at the beginning to mark it as
  • 00:04:09 a relative import store like this now in
  • 00:04:13 order to finally make this work I have
  • 00:04:14 to adjust my reducer files here in order
  • 00:04:17 to be able to export a fat arrow
  • 00:04:19 function what I need to do is I need to
  • 00:04:23 actually store that in a new constant
  • 00:04:26 which I'll name
  • 00:04:27 Moff reducer oops
  • 00:04:31 like this and then export this Moff
  • 00:04:35 reducer constant here without
  • 00:04:38 parentheses so simply put a number words
  • 00:04:43 make it a constant and then export this
  • 00:04:48 constant here like this so if I save
  • 00:04:52 this and reload my application it works
  • 00:04:55 it works if I click this button so now I
  • 00:04:58 split up my reducers I have my smart and
  • 00:05:01 dumb components we're still missing the
  • 00:05:04 actions though so let's take care about
  • 00:05:06 this here I'll also create you new files
  • 00:05:09 the math actions and the user actions
  • 00:05:16 like so now how do i define such actions
  • 00:05:20 actions here i will export multiple
  • 00:05:24 functions here I'll name it add number
  • 00:05:29 for example we'll get a number here and
  • 00:05:33 this will simply return a JavaScript
  • 00:05:36 object setting the type add and setting
  • 00:05:42 the payload to number so that's just one
  • 00:05:47 function I'm going to duplicate this and
  • 00:05:50 have my subtract number function here
  • 00:05:53 which is also the same but with subtract
  • 00:05:58 here as a type and as you can see these
  • 00:06:00 types here are or the way I set them up
  • 00:06:04 here is just as JavaScript object and
  • 00:06:06 dispatching later on that's all these
  • 00:06:08 functions are returning they are
  • 00:06:10 returning this JavaScript object which I
  • 00:06:12 wanted to Spach later on now I'm copying
  • 00:06:15 all this and in my user actions I'll set
  • 00:06:22 up set name and set H here I'll pass H
  • 00:06:27 and name name and age rename this set
  • 00:06:34 name and this to set H like this and now
  • 00:06:39 to hook this up I'll go to my app chest
  • 00:06:41 file and here in the map dispatch to
  • 00:06:44 props where I want to hook up set name
  • 00:06:46 well I still want you hook up set name
  • 00:06:49 and I want to pass name but here I'm
  • 00:06:53 calling dispatch on set name and pass
  • 00:06:57 this name now what is set name here well
  • 00:07:01 set name is something I import from my
  • 00:07:03 actions so import from actions math
  • 00:07:13 actions here for example and I want to
  • 00:07:17 import no not math user actions and I
  • 00:07:21 want to import set name like so and it
  • 00:07:28 should be double quotation marks outside
  • 00:07:30 now to stay consistent so now I'm doing
  • 00:07:35 this if I save this reload my app click
  • 00:07:38 this button it's still working as you
  • 00:07:41 see but now I'm using these actions
  • 00:07:43 files now it would be a valid point to
  • 00:07:48 ask well what's the advantage I still
  • 00:07:52 can't use duplicate action names I still
  • 00:07:56 have the same problem as before if I
  • 00:07:58 want to use a action with a type of add
  • 00:08:03 here I would still have the problem that
  • 00:08:06 I also trigger my math reducer which
  • 00:08:09 listens to add right and now I split it
  • 00:08:13 up over multiple files but what's the
  • 00:08:16 advantage of this the advantage is that
  • 00:08:18 in bigger applications it's much easier
  • 00:08:21 for you to manage your actions and
  • 00:08:24 reducers you're probably seeing the
  • 00:08:27 pattern here that I have math actions
  • 00:08:29 and am off reducer user actions and a
  • 00:08:31 user reducer and I have clear clear
  • 00:08:34 mappings of what I want to use there it
  • 00:08:37 makes very easy for me to maintain
  • 00:08:40 bigger applications to add new actions
  • 00:08:43 to change existing ones and to make sure
  • 00:08:45 that I'm using these actions in the
  • 00:08:50 right way or that I don't get one big
  • 00:08:54 file
  • 00:08:55 all factions and one big file off
  • 00:08:57 reducers but instead I split them up by
  • 00:08:59 features which makes it far more
  • 00:09:02 manageable regarding the issue of having
  • 00:09:06 the problem that I overwrite my my names
  • 00:09:11 for my types here well one workaround
  • 00:09:14 would simply be to prefix your types so
  • 00:09:17 you could see say that set that you have
  • 00:09:20 user set name here at the beginning
  • 00:09:22 since we're in the user actions file and
  • 00:09:26 then of course you will also change your
  • 00:09:27 reducer to listen to user set name and
  • 00:09:30 so on so that overall makes your
  • 00:09:33 application much more manageable and
  • 00:09:34 much cleaner now rightfully you would
  • 00:09:38 say that we're using a lot of
  • 00:09:40 boilerplate code here for this very
  • 00:09:43 basic app here and you would be right
  • 00:09:46 such a simple app is probably nothing
  • 00:09:49 where you want to use Redux but in more
  • 00:09:51 complex apps you'll quickly see it shine
  • 00:09:54 and this initial boilerplate which we
  • 00:09:57 set up here all these files and folders
  • 00:10:00 doesn't have to be expanded anymore
  • 00:10:02 you'll only use or add some new reducers
  • 00:10:05 and action files and components and
  • 00:10:08 containers but you don't have to add
  • 00:10:11 multiple new folders or write much more
  • 00:10:14 code in any of these core root files
  • 00:10:18 here and that's the advantage it's much
  • 00:10:21 more manageable your state as clearly
  • 00:10:23 manage and so is your app