Coding

React Context vs Redux – Who wins?

  • 00:00:01 hi and welcome to this video should you
  • 00:00:04 use react Redux or react context or HD
  • 00:00:09 context API killing react Redux and
  • 00:00:11 these are questions you see quite a bit
  • 00:00:13 and here's my take on that and will
  • 00:00:15 actually take this application here
  • 00:00:17 which uses redux right now and for which
  • 00:00:21 I'll walk you real quick and could word
  • 00:00:23 it fully to the context API so that you
  • 00:00:25 can see for yourselves
  • 00:00:27 if it's worth it if you like that
  • 00:00:28 approach and if it's better than redux
  • 00:00:33 so here we have a little demo
  • 00:00:35 application link of forest below the
  • 00:00:37 video and this is a very very very very
  • 00:00:41 simple shop which has basically a few
  • 00:00:45 products here which you can add to the
  • 00:00:47 cart and you'll notice a lot a slight
  • 00:00:50 delay here as I do add them if we have a
  • 00:00:52 look at the cart we see them here also
  • 00:00:55 with a quantity being updated if we um
  • 00:00:57 remove them or add them we have a slight
  • 00:01:00 delay in there basically to just
  • 00:01:01 simulate that we're also talking to a
  • 00:01:03 server I could have added a spinner or
  • 00:01:06 anything like that but it's not so much
  • 00:01:07 about the UI here but about the
  • 00:01:09 functionality speaking of that if we
  • 00:01:11 have a look at the code what I got in
  • 00:01:13 there is I'm using Redux so I'm setting
  • 00:01:17 up my store here in the Enix J's file
  • 00:01:19 and we'll have a look at these redux
  • 00:01:20 files in a second let's first of all
  • 00:01:22 dive into the app I got my app.js file
  • 00:01:25 in which I do set up my router my react
  • 00:01:29 router here I have two routes one for
  • 00:01:32 the products page and one for the card
  • 00:01:34 page if we have a look at these routes
  • 00:01:37 well essentially in a products page I
  • 00:01:40 render a list of products which I do get
  • 00:01:42 from redux with map States you brought
  • 00:01:45 two props in the main navigation which
  • 00:01:49 is a separate component I do pass my
  • 00:01:51 card item number because I do show that
  • 00:01:54 card item number here next to my cart
  • 00:01:56 link in the main navigation so here I
  • 00:01:59 received that as a prop and I do pass it
  • 00:02:02 in from both products and the card page
  • 00:02:04 in the cart page I get my cart items
  • 00:02:07 with map state two props and I then
  • 00:02:10 render my card items here and I got some
  • 00:02:12 styling and so on now I do you assume
  • 00:02:14 that you know the basics about redux
  • 00:02:16 otherwise you probably wouldn't be
  • 00:02:18 wondering if context is better than that
  • 00:02:20 just to give you a brief refresher on
  • 00:02:23 redux and how it works here in the store
  • 00:02:26 folder I have my Redux actions because
  • 00:02:29 Redux is all about dispatching actions
  • 00:02:31 which then changed at central store
  • 00:02:33 because in its core the idea the
  • 00:02:36 important thing about read access that
  • 00:02:38 you have one central store in your
  • 00:02:40 application which you can then tap into
  • 00:02:43 from different parts in your app if you
  • 00:02:45 want to change it your dispatch an
  • 00:02:46 action
  • 00:02:47 if you want to get something out of
  • 00:02:48 there you use this map stage two props
  • 00:02:51 approach I'll come back to in a second
  • 00:02:53 so I got actions in Here I am using
  • 00:02:57 redux
  • 00:02:58 funk setup here in index.js when I
  • 00:03:01 create my store here and that
  • 00:03:03 essentially allows me to execute async
  • 00:03:06 code in my action creators which are
  • 00:03:08 these functions where you could reach
  • 00:03:10 out to a web server or as I do it here
  • 00:03:13 you set some time out to simulate an API
  • 00:03:15 call as I do it here and then after the
  • 00:03:18 timeout I do this patch my ad product to
  • 00:03:20 card or my remove car a product from
  • 00:03:23 card action now these actions are being
  • 00:03:26 dispatched from inside my app they are
  • 00:03:28 made available to my components with map
  • 00:03:31 dispatch two props and map states two
  • 00:03:34 props and map dispatch two props these
  • 00:03:36 are functions I defined here which I can
  • 00:03:39 pass to that connect higher-order
  • 00:03:41 component which in turn is made
  • 00:03:43 available by the react Redux package and
  • 00:03:47 this is essentially how you connect a
  • 00:03:48 component to the global Redux store this
  • 00:03:52 allows you to tap into it and get data
  • 00:03:54 or dispatch actions to it so this is how
  • 00:03:58 this flow of data is if we have a look
  • 00:04:00 at the reducer which is essentially the
  • 00:04:02 function getting executed when an action
  • 00:04:05 is dispatched in that reducer I have in
  • 00:04:08 here I do have an initial state with
  • 00:04:09 some dummy products here in the initial
  • 00:04:11 state and then that reducer function
  • 00:04:13 here I do a check for my two action
  • 00:04:17 cases add product card and remove
  • 00:04:19 product from card and then I just update
  • 00:04:22 my card array here to either add an item
  • 00:04:25 if it isn't in there already or if it is
  • 00:04:28 in there already I just update its
  • 00:04:30 quantity and that is essentially what I
  • 00:04:33 do here and the same for removing feel
  • 00:04:35 free to go through that in detail you do
  • 00:04:37 have to code after all so this is a
  • 00:04:39 classic Redux set up let's now convert
  • 00:04:43 this to the context API which is a
  • 00:04:45 feature built-in to react because right
  • 00:04:47 now read acts of course is a third party
  • 00:04:49 package I did install react
  • 00:04:51 Redux here and I installed Redux and
  • 00:04:54 redux func some free extra packages to
  • 00:04:57 add this functionality and of course
  • 00:04:59 that adds to our
  • 00:05:00 mandal sighs so if we can get rid of
  • 00:05:02 that with a reasonable effort it might
  • 00:05:05 be worth it because we ship less code to
  • 00:05:07 our users if we find ourselves writing a
  • 00:05:10 lot of extra code we might not be doing
  • 00:05:12 that though so let's find how much
  • 00:05:14 effort it takes now the idea behind the
  • 00:05:18 context API in reactors that you can
  • 00:05:21 provide context which essentially is
  • 00:05:23 just a JavaScript object you could say
  • 00:05:25 you provided at some point in your app
  • 00:05:27 could be in your route app component
  • 00:05:29 could be in an average component and all
  • 00:05:32 child components off the component where
  • 00:05:35 you provided in then have access to that
  • 00:05:37 context so they have access to this
  • 00:05:39 JavaScript object you provide this is
  • 00:05:42 kind of the idea of that central store
  • 00:05:44 and Redux just a bit more flexible
  • 00:05:46 because if you want to have one central
  • 00:05:48 context you can do it in your root
  • 00:05:50 component in your topmost component or
  • 00:05:53 if you will only need state in a part of
  • 00:05:56 your app you provide that context in
  • 00:05:58 that part by providing it on a component
  • 00:06:01 a little further down in your component
  • 00:06:04 stream so here I actually want to have a
  • 00:06:06 global state and therefore what I'll do
  • 00:06:08 is I'll add a new folder context to kind
  • 00:06:12 of kind of differentiate it from my
  • 00:06:13 store folder and I will add my shop
  • 00:06:16 context JS file in there now I want to
  • 00:06:20 create my context object in this file so
  • 00:06:23 that I can then import it into the
  • 00:06:25 different parts of my app where I need
  • 00:06:27 to access it so how do we create such a
  • 00:06:30 context in react well we can simply
  • 00:06:33 import react from react first of all
  • 00:06:37 because the context thing is baked into
  • 00:06:39 react so we need to access it on the
  • 00:06:41 react object and there we have a create
  • 00:06:44 context function now create context this
  • 00:06:48 function takes a default value as a
  • 00:06:51 first argument so we can pass in a
  • 00:06:53 default JavaScript object and I
  • 00:06:55 recommend doing that because even though
  • 00:06:57 you don't technically need it as you
  • 00:06:59 will learn and at least not in this
  • 00:07:01 example if you add it here you get
  • 00:07:03 better auto completion in your IDE which
  • 00:07:05 is definitely worth it now in the end
  • 00:07:08 the data I want a store here is of
  • 00:07:10 course still the same data as before I
  • 00:07:12 need my products and my card array
  • 00:07:14 so we'll just copy that here from my
  • 00:07:17 store reducers file and move it into
  • 00:07:20 this object which I'm creating here now
  • 00:07:23 using the context in this file would be
  • 00:07:25 nice but not really it's not really what
  • 00:07:28 we need to do we need to use this
  • 00:07:30 context from outside this file we want
  • 00:07:32 to use it in our other components so
  • 00:07:34 let's export this as a default by simply
  • 00:07:37 adding export default in front of that
  • 00:07:39 created context now we can import from
  • 00:07:42 that file and let's import in the app.js
  • 00:07:44 file where I want to provide that
  • 00:07:46 context because in all child components
  • 00:07:49 of the app J's file even if they're
  • 00:07:51 loaded by routing I can thereafter tap
  • 00:07:54 into that context so in here let me
  • 00:07:58 import my shop context and you should
  • 00:08:02 import this with an upper case starting
  • 00:08:04 character because we'll use it like a
  • 00:08:06 component from and now let's point at
  • 00:08:11 that context folder and then the shop
  • 00:08:13 context file in there to now provide
  • 00:08:16 that context you basically wrap your
  • 00:08:19 components that should be able to access
  • 00:08:21 it with shop context or whatever you
  • 00:08:24 named it dot provider you do that here
  • 00:08:30 around my in this case this routing
  • 00:08:33 setup so that all the loaded components
  • 00:08:36 loaded through these routes can tap into
  • 00:08:38 that now here comes the cool thing you
  • 00:08:42 can now set a value here and this is the
  • 00:08:44 day that the concrete data that is
  • 00:08:47 passed down to all these components now
  • 00:08:49 obviously I do set a default value here
  • 00:08:52 right I do set this default value so it
  • 00:08:55 wouldn't need to pass a specific value
  • 00:08:57 just to have that but of course we don't
  • 00:08:59 want to stay at this default value we
  • 00:09:03 want to change that over time and
  • 00:09:04 therefore here in app jeaious we of
  • 00:09:07 course don't just have to set some
  • 00:09:08 static one-time initial value this is
  • 00:09:11 the value which when we update it will
  • 00:09:14 be passed down to the child components
  • 00:09:15 and we'll update those as well so
  • 00:09:18 therefore here in my app component I can
  • 00:09:20 now use my internal state the default
  • 00:09:23 state I can have in any class-based
  • 00:09:25 component and the same would be to
  • 00:09:27 review use hooks
  • 00:09:28 you can then do this with the use state
  • 00:09:30 hook so here I'm using the class based
  • 00:09:32 approach here in this state
  • 00:09:35 I can now again let's say start with
  • 00:09:39 this initial setup and therefore we
  • 00:09:41 could of course remove it from that shop
  • 00:09:43 context file or start with an empty
  • 00:09:45 products array here too to just have the
  • 00:09:47 auto completion because now I will
  • 00:09:49 initialize this here in this state in
  • 00:09:52 the App J's file and in here I also now
  • 00:09:55 want to add my add product to cart
  • 00:10:00 method where I get the product as an
  • 00:10:03 argument let's say and I also want to
  • 00:10:07 add my remove product from card method
  • 00:10:11 where I get the product ID and that do
  • 00:10:13 something so essentially the methods I
  • 00:10:16 previously had in my reducer here now
  • 00:10:20 these functions are added to the app
  • 00:10:21 trace file and of course that as I
  • 00:10:24 mentioned before it doesn't have to be
  • 00:10:26 the app.js file it is the file where you
  • 00:10:28 want to provide this context and you of
  • 00:10:30 course you can have multiple contexts in
  • 00:10:32 one at the same app so you don't have to
  • 00:10:34 have one gigantic context in here just
  • 00:10:37 as you can split reducers in a Redux
  • 00:10:39 setup you can have different contexts
  • 00:10:41 which are provided in different
  • 00:10:43 components you can even create wrapper
  • 00:10:45 components to not clutter your app
  • 00:10:48 component with all the logic so use
  • 00:10:50 regular react features to split that as
  • 00:10:54 you want here I'll stay in the app.js
  • 00:10:57 file and I do have my two methods here
  • 00:11:00 and in my value here I will now pass in
  • 00:11:04 a JavaScript object hence the double
  • 00:11:06 curly braces first pair sets up by
  • 00:11:08 dynamic value inner pair then creates a
  • 00:11:11 JavaScript object and I want to pass
  • 00:11:13 down my products which refer to this
  • 00:11:15 state products I want to pass down my
  • 00:11:18 cart which refers to this state cart so
  • 00:11:21 to my state values and now comes the fun
  • 00:11:24 part I want to be able to call these
  • 00:11:27 methods from inside our components so
  • 00:11:31 from the components that receive my
  • 00:11:33 context to make this possible I just
  • 00:11:35 have to add references to these methods
  • 00:11:37 into my context object down there
  • 00:11:41 so besides passing products and cart I
  • 00:11:44 will now also add add product to cart
  • 00:11:47 and you can name this whatever you want
  • 00:11:49 and this should point at this add
  • 00:11:52 product to cart so it should point at
  • 00:11:55 this method important don't execute it
  • 00:11:58 here you don't want to run it
  • 00:11:59 immediately when this is parsed instead
  • 00:12:02 you just want to pass a reference so
  • 00:12:04 that this is executed when add product
  • 00:12:07 to cart is called from inside a child
  • 00:12:09 component just as you would pass a
  • 00:12:11 reference to an onclicklistener for
  • 00:12:13 example now I'll do the same for
  • 00:12:16 removing so remove products from
  • 00:12:18 Carville point at this remove product
  • 00:12:20 from cart also without parentheses now
  • 00:12:23 to get better order completion I will
  • 00:12:25 also add this to my default value here
  • 00:12:28 add product to cart and this year will
  • 00:12:32 just be an empty method which does
  • 00:12:34 nothing and I simply added here to get
  • 00:12:36 better Auto completion that's all so
  • 00:12:39 remove product from card as added there
  • 00:12:41 as well and I do get my product here
  • 00:12:46 though and here I will get a product ID
  • 00:12:49 and with this setup added we got our
  • 00:12:53 core state setup now let's add some
  • 00:12:57 functionality to add product to card and
  • 00:12:59 remove product from crowd so for now it
  • 00:13:02 will simply console.log adding product
  • 00:13:06 and basically just oops output my
  • 00:13:11 product here and do the same for
  • 00:13:13 removing so that we can see if that was
  • 00:13:15 triggered correctly so removing product
  • 00:13:18 with ID and then here we can concatenate
  • 00:13:22 our Product ID so now we should be able
  • 00:13:26 to see these console locks but of course
  • 00:13:28 for dad we now need to access that
  • 00:13:30 context from the child components
  • 00:13:32 because we're still working in the app
  • 00:13:34 j/s and the root component only let's
  • 00:13:37 start with products where we want to add
  • 00:13:38 our product to the cart first of all I
  • 00:13:43 will get rid of connect down there this
  • 00:13:49 is a react Redux thing and we don't need
  • 00:13:51 it anymore so I can get rid of that you
  • 00:13:53 could now delete map State
  • 00:13:55 to props and map dispatch to props all
  • 00:13:57 commented out so that we have it here
  • 00:13:59 for reference but we won't need it
  • 00:14:01 anymore
  • 00:14:02 instead in here in the products page we
  • 00:14:05 now want to access our context the way
  • 00:14:08 let me comment these unused imports out
  • 00:14:10 as well so we want to use our context in
  • 00:14:13 here and now we have two ways of tapping
  • 00:14:15 into the context both ways require us to
  • 00:14:18 import our context so let's do that
  • 00:14:20 first I'll import my shop context and
  • 00:14:22 you can name it here as you want doesn't
  • 00:14:24 have to have the same name as an app
  • 00:14:26 trace because it still will point at the
  • 00:14:28 same object I import my shop context by
  • 00:14:32 going up into the context folder and
  • 00:14:34 then to the shop context file now method
  • 00:14:37 1 of importing it or of using it is that
  • 00:14:40 we use it down there where we returned J
  • 00:14:42 as xcode for this component and you can
  • 00:14:45 use this in a functional component as
  • 00:14:47 well you use your shop context and then
  • 00:14:51 add consumer we had dot provider in app
  • 00:14:54 j s here we can add dot consumer we wrap
  • 00:14:58 our entire J's X code with that and in
  • 00:15:01 there we get a so-called render prop
  • 00:15:03 which means we have a dynamic content in
  • 00:15:06 here which will be a JavaScript function
  • 00:15:09 that should return the JSX code we want
  • 00:15:12 to render for this component so what we
  • 00:15:14 previously had returned in our render
  • 00:15:18 method we add us now here in this
  • 00:15:20 function we have between our and curly
  • 00:15:22 braces like this and there we receive
  • 00:15:25 context as an argument and this refers
  • 00:15:28 to our object as we pass it here into
  • 00:15:32 the provider so we have access to
  • 00:15:34 exactly this object in our products page
  • 00:15:36 now and this means that there for
  • 00:15:41 example where I want to output my my
  • 00:15:45 cart item number number I can now tap
  • 00:15:47 into my context get access to the cart
  • 00:15:51 and use the same logic I had down there
  • 00:15:55 here I had this reduce function add to
  • 00:15:58 calculate the quantity of items so let
  • 00:16:01 me bring that up there comment these
  • 00:16:05 parts back and of course so now what I
  • 00:16:08 have here is
  • 00:16:09 my main navigation gets the car that
  • 00:16:10 number which in the end taps into the
  • 00:16:13 context they are into this card array
  • 00:16:15 and reduces this array to a single
  • 00:16:17 number that indicates how many items are
  • 00:16:19 in the card by adding the quantity of
  • 00:16:22 each item and starting with a quantity
  • 00:16:24 of 0 of course now this is one part we
  • 00:16:27 also want to go through all our products
  • 00:16:30 and for this here again we just use that
  • 00:16:32 context argument we're getting here the
  • 00:16:36 era can access the products because if
  • 00:16:38 you have a look at the app tray as file
  • 00:16:39 we do have a products field on our
  • 00:16:41 context and then we can read all the
  • 00:16:45 values in there and of course here I
  • 00:16:47 want to add a product to the card so I
  • 00:16:50 can just use context add product to cart
  • 00:16:52 because I have the add product to card
  • 00:16:55 function here or method here in my
  • 00:16:58 context object if we save all of that we
  • 00:17:03 go to products and reload this page
  • 00:17:05 let's open our developer tools in the
  • 00:17:08 JavaScript console and let's click Add
  • 00:17:11 to Cart and you should be seeing adding
  • 00:17:14 product and then this Gaming Mouse here
  • 00:17:17 or the plastic bottle so this seems to
  • 00:17:20 work as you can tell and this is now
  • 00:17:22 using the context API only in the
  • 00:17:24 product page thus far hence we see no
  • 00:17:26 update here in the cart we also haven't
  • 00:17:31 added any logic to really do something
  • 00:17:34 on the cart here in app jeaious now I
  • 00:17:38 also mentioned that this is only one way
  • 00:17:39 of adding the context here with consumer
  • 00:17:41 the advantage of this approach is that
  • 00:17:43 it works in both class-based and
  • 00:17:45 functional components the downside is
  • 00:17:48 that this only gives you access to the
  • 00:17:51 context in your render part where you
  • 00:17:54 render your JSX code if you need access
  • 00:17:56 to the context in component it mount or
  • 00:17:59 in the constructor then you're lost at
  • 00:18:02 this will not work there so let's have a
  • 00:18:05 look at approach number two in the cart
  • 00:18:07 page again I want to access my context I
  • 00:18:12 want to use it so let's import shop
  • 00:18:14 context from and go into the context
  • 00:18:17 folder and import it from the shop
  • 00:18:18 context file and now instead of you
  • 00:18:21 in context shop context consumer which
  • 00:18:24 we could do let's use an approach which
  • 00:18:26 will only work in class-based components
  • 00:18:28 not in functional components we can add
  • 00:18:33 a static property to this class-based
  • 00:18:36 component by adding the static keyword
  • 00:18:38 and then this property has to be named
  • 00:18:40 context type important
  • 00:18:44 this requires react version 16.6 or
  • 00:18:47 higher it will not work in lower
  • 00:18:49 versions you set this equal to shop
  • 00:18:53 context so to the context you imported
  • 00:18:56 behind-the-scenes react will now connect
  • 00:18:58 to this context and give you access to a
  • 00:19:01 special this context property which is
  • 00:19:04 made available by react which gives you
  • 00:19:07 access to that context object passed
  • 00:19:09 down through this context now if you
  • 00:19:12 have multiple contexts you want to
  • 00:19:13 access in this component you need to get
  • 00:19:15 creative and for example create some
  • 00:19:17 wrapper components or anything like that
  • 00:19:19 so here we now have access to this
  • 00:19:22 context which means we could now also
  • 00:19:25 use our context in component did mount
  • 00:19:28 for example so if i added this year and
  • 00:19:31 i console.log this context if I save
  • 00:19:35 that and I go to the card component
  • 00:19:38 indeed here I see my context object
  • 00:19:40 being locked with the default products
  • 00:19:42 so this is a pretty nice we now don't
  • 00:19:46 have to use context consumer down there
  • 00:19:48 instead here where I want to get that
  • 00:19:50 card item count well instead of using
  • 00:19:54 connect here we can get rid of that and
  • 00:19:57 therefore instead of using math dispatch
  • 00:20:00 to props and that's the maps tied to
  • 00:20:02 props I can again use this reduce
  • 00:20:05 function on my card and use it up there
  • 00:20:09 and access this context whoops
  • 00:20:13 dot card reduce and comment this back in
  • 00:20:17 just as I did before but now not with
  • 00:20:20 the consumer but with this context made
  • 00:20:23 available by the static context type
  • 00:20:25 here and I can do this anywhere where I
  • 00:20:27 need data from my context like here
  • 00:20:30 where I want to get my card items now I
  • 00:20:33 can access this context card
  • 00:20:35 because here I did rename it to card
  • 00:20:37 items whether us redox it's all in that
  • 00:20:40 card array we have in a context though
  • 00:20:42 the same down there this context cart
  • 00:20:48 allows me to tap into the items that are
  • 00:20:50 in the cart if I want to remove an item
  • 00:20:53 I can execute this context remove
  • 00:20:55 product from cart and here I do pass in
  • 00:20:58 that ID I want to remove with the bind
  • 00:21:00 method now let me remove the unused
  • 00:21:05 imports here as well and if we now save
  • 00:21:08 this on the cart page we of course have
  • 00:21:11 no items in there to see if that works
  • 00:21:13 so let's finish this up by going to the
  • 00:21:16 reducer and there in my ad product card
  • 00:21:21 case this essentially is the logic I now
  • 00:21:24 want to copy and add to app KS to my ad
  • 00:21:29 product to card function in there so in
  • 00:21:32 here I will create a new constant
  • 00:21:37 updated cart and updated item index
  • 00:21:41 there I want to access my current card
  • 00:21:43 from this state and I no longer get an
  • 00:21:47 action with a payload instead here I do
  • 00:21:50 get my product as an argument I do
  • 00:21:53 expect to get that and I can access the
  • 00:21:55 idea on that since every product has an
  • 00:21:57 ID in this application I then do update
  • 00:22:01 my cart by pushing a new item on it if
  • 00:22:04 this item hasn't been added to it before
  • 00:22:05 and instead of action payload I just
  • 00:22:08 pushed a product I'm getting as an
  • 00:22:09 argument
  • 00:22:10 I set the quantity to 1 there and if I
  • 00:22:13 had this item in the cart already I just
  • 00:22:15 increase the quantity now let me all to
  • 00:22:18 copy the logic for removing an item here
  • 00:22:20 from the remove product from cart case
  • 00:22:23 let's copy all of that go back to you AB
  • 00:22:26 KS and in remove product from cart I'll
  • 00:22:30 add this here add a Const keyword in
  • 00:22:33 front of updated card and in front of
  • 00:22:35 updated item index here we access this
  • 00:22:37 state cart and we do get our product ID
  • 00:22:42 as an argument here now then we update
  • 00:22:46 the cart in both cases I now
  • 00:22:48 want to update the state of a purchase
  • 00:22:50 because this is where I manage that data
  • 00:22:53 I do pass down through the context
  • 00:22:55 remember here
  • 00:22:56 I'm just accessing my state to get the
  • 00:22:58 data a pass in my context object hence I
  • 00:23:01 need to update the state of this
  • 00:23:02 component to update what I passed down
  • 00:23:05 with context so here in add product I
  • 00:23:08 call this set state and I set card here
  • 00:23:13 to my updated card I don't need to touch
  • 00:23:15 my products there because I don't change
  • 00:23:17 them here and remove product from card
  • 00:23:20 it's the same I just said my card – the
  • 00:23:22 updated card with that I should have
  • 00:23:27 logic in there that works so let's save
  • 00:23:30 all files if I now click add to product
  • 00:23:33 I got this instant update because I
  • 00:23:35 removed that delay I'll riad it and in
  • 00:23:38 the cart page we see it there as well
  • 00:23:41 now if I add more gaming mouses here we
  • 00:23:44 see that it's grouped together and I can
  • 00:23:46 remove items that all updates correctly
  • 00:23:48 also in the header now to reintroduce
  • 00:23:52 that timeout you don't need a special
  • 00:23:54 middleware for that as you needed it for
  • 00:23:56 Redux
  • 00:23:56 you can simply add it here in the
  • 00:23:58 function that executes so an Add to Cart
  • 00:24:01 at product two card if you want to make
  • 00:24:04 sure that this happens only after a
  • 00:24:05 small timeout you can just add set
  • 00:24:08 timeout here and do your state update
  • 00:24:12 only after that time of course this is
  • 00:24:14 just some dummy code in reality you
  • 00:24:16 would not set and a timeout you would be
  • 00:24:19 making an HTTP request at the beginning
  • 00:24:21 and then update your state and the then
  • 00:24:23 block or anything like that so let me do
  • 00:24:26 the same here now for for removing a
  • 00:24:31 product from the cart
  • 00:24:32 let's X let's add a function that will
  • 00:24:35 execute after these seven hundred
  • 00:24:37 milliseconds and with this tiny change
  • 00:24:39 if I go back to products now you will
  • 00:24:41 see it doesn't update immediately in the
  • 00:24:43 header it takes a short while because of
  • 00:24:46 that delay I did add but I've read and
  • 00:24:48 added of course works the same so that
  • 00:24:52 is the context added here the context
  • 00:24:55 replacing Redux we could now remove that
  • 00:24:58 store folder all redux imports
  • 00:25:02 we can now remove redox funk redox and
  • 00:25:05 react reacts from the package and we
  • 00:25:07 therefore have way less dependencies to
  • 00:25:09 achieve basically the same downsides
  • 00:25:12 would be that if you have a lot of
  • 00:25:13 global state you will end up with a huge
  • 00:25:16 app component or you create a dedicated
  • 00:25:19 component that holds your state and
  • 00:25:22 passes it down as props to the component
  • 00:25:25 that wraps and the app component would
  • 00:25:27 be that wrapped component and that could
  • 00:25:29 then remove logic from your app
  • 00:25:30 component let me actually show you that
  • 00:25:32 for that I'll add here in the context
  • 00:25:35 folder I'll have my global state
  • 00:25:40 component you can name it whatever you
  • 00:25:42 want and in there we can import react
  • 00:25:45 and component from oops from react like
  • 00:25:49 this and then I want to add my class
  • 00:25:52 global State and you can name this
  • 00:25:54 whatever you want
  • 00:25:55 doesn't have to be named global State
  • 00:25:57 and here I extend component and in my
  • 00:26:02 render function I now just want to
  • 00:26:05 return this props children so whatever I
  • 00:26:10 pass between the opening and closing tag
  • 00:26:12 off the global state component when I
  • 00:26:13 use it the interesting part is that I
  • 00:26:16 will now add the logic I had here in app
  • 00:26:18 jeaious for the state and these methods
  • 00:26:22 here I will cut that from app J's and
  • 00:26:26 add it to the global state so that all
  • 00:26:28 the logic is in here and I will export
  • 00:26:33 my global State of course as a default
  • 00:26:35 in that file so export default global
  • 00:26:38 state and now we have that logic in the
  • 00:26:41 global State in app j/s I now can remove
  • 00:26:45 that shop context import and instead
  • 00:26:48 here in global State I want to import
  • 00:26:50 shop context from the shop context file
  • 00:26:53 which is in the same folder as global
  • 00:26:56 State because here I will actually now
  • 00:26:59 not just return this props children but
  • 00:27:03 I will wrap that robber I will wrap it
  • 00:27:05 with shop context provider because you
  • 00:27:12 have to remember that the provider
  • 00:27:15 provides
  • 00:27:15 it's the context which I have to pass
  • 00:27:17 here through the value to all its
  • 00:27:20 children and if I now use that global
  • 00:27:24 state as a wrapper around my AB
  • 00:27:27 component or around whatever I have here
  • 00:27:29 then still all the child components
  • 00:27:32 there have access to that state but that
  • 00:27:34 logic for that state is now not packed
  • 00:27:36 into the app component but out sourced
  • 00:27:38 technically the result will be the same
  • 00:27:41 but it gives you cleaner code and allows
  • 00:27:43 you to split your code more elegantly so
  • 00:27:46 that is possible with the context so the
  • 00:27:49 downside of having a big app.js file
  • 00:27:52 isn't really there let me show you how
  • 00:27:54 this would work I now just need to
  • 00:27:56 import my global state component from
  • 00:27:59 the context file and there from global
  • 00:28:03 State and then I will cut my value
  • 00:28:11 object here because I needed in a second
  • 00:28:12 but I can then wrap my router here with
  • 00:28:17 global state and also close that here so
  • 00:28:22 now I'm wrapping my router with just
  • 00:28:23 global State an in global state here
  • 00:28:27 that value I passed to my shop context
  • 00:28:30 provider is that object I just cut from
  • 00:28:33 app jeaious where I refer to the
  • 00:28:35 products and cards state of the global
  • 00:28:37 state component and where I add these
  • 00:28:39 methods and global state is really just
  • 00:28:41 a normal react component right I do
  • 00:28:44 extend component I just use it as a
  • 00:28:46 wrapper component to do all that state
  • 00:28:48 management and have all the state
  • 00:28:50 management code in there so that my app
  • 00:28:52 component can stay lean and with that a
  • 00:28:57 lot of talking if I save that and the
  • 00:29:00 app reloads it still works as before
  • 00:29:03 because we didn't change anything
  • 00:29:05 logically just make our code a little
  • 00:29:07 bit easier to read so should you always
  • 00:29:10 use the context API then well on the
  • 00:29:14 first look it might look like an obvious
  • 00:29:16 answer sure you should it's relatively
  • 00:29:18 easy to use it saves you the extra
  • 00:29:21 dependency and therefore probably also
  • 00:29:23 shrinks your bundle size and why
  • 00:29:25 wouldn't you use it if it's baked and to
  • 00:29:27 react well let's have a look at
  • 00:29:29 quote from someone involved with the
  • 00:29:31 development of react and therefore
  • 00:29:33 certainly someone who has some insights
  • 00:29:37 into what happens behind the scenes and
  • 00:29:39 there we learn that even people in the
  • 00:29:42 react team are not convinced that you
  • 00:29:43 should use the context API for
  • 00:29:45 high-frequency updates for low frequency
  • 00:29:49 changes like the user picked a different
  • 00:29:50 theme the user locked in or at user
  • 00:29:54 changed the locale off that application
  • 00:29:56 it might be great but due to the way the
  • 00:29:59 context API works internally where react
  • 00:30:02 essentially has to traverse the entire
  • 00:30:04 tree off components it constructs to
  • 00:30:07 detect state changes and handle them
  • 00:30:10 roughly speaking because of that it's
  • 00:30:13 not ideal to use the context API with a
  • 00:30:16 global State for high frequency changes
  • 00:30:18 so you should definitely not store every
  • 00:30:21 keystroke made by a user in their
  • 00:30:22 context API now that of course does not
  • 00:30:24 mean you should never use the context
  • 00:30:27 API use it with care use it for low
  • 00:30:31 frequency updates so for state changes
  • 00:30:33 that don't occur multiple times per
  • 00:30:35 second and definitely consider it for
  • 00:30:38 these use cases maybe you can store and
  • 00:30:40 were handled the higher frequency
  • 00:30:41 updates differently with props or inside
  • 00:30:44 of your component then you still might
  • 00:30:45 not need Redux and the thing where you
  • 00:30:48 would have used it otherwise can be
  • 00:30:50 replaced with the context API but if you
  • 00:30:52 were building an app where you're
  • 00:30:54 storing a lot in Redux and amongst all
  • 00:30:56 that state and data all the things that
  • 00:30:59 change frequently in cases like this you
  • 00:31:02 might consider not using the context API
  • 00:31:05 for that but stick to Redux because the
  • 00:31:07 context API is really just not built as
  • 00:31:10 a replacement for Redux that's not its
  • 00:31:13 core idea that is not the reason why it
  • 00:31:16 was added to react and therefore don't
  • 00:31:18 use it for this but consider it for the
  • 00:31:21 use case as I mentioned before mostly
  • 00:31:23 low frequency updates and there it's
  • 00:31:25 great to use and definitely a great
  • 00:31:27 replacement for Redux