- 00:00:00 in the last video we ended up with our
- 00:00:03 basics redox flow here where we had an
- 00:00:07 initial state of a number of one and
- 00:00:09 then we just patched some actions to add
- 00:00:12 and subtract values to that value and as
- 00:00:16 you can see this works fine now
- 00:00:18 typically your application doesn't use a
- 00:00:22 number as a state it might use an object
- 00:00:27 instead and you might want to change
- 00:00:30 your values in that object it also might
- 00:00:34 use arrays and since objects and arrays
- 00:00:37 are reference types which means they are
- 00:00:41 no primitives which get copied but
- 00:00:44 instead have one place in memory and
- 00:00:47 then pointers pointing to that place we
- 00:00:51 want to make sure that we're changing
- 00:00:52 the state in an immutable way which
- 00:00:55 means we're always taking the old state
- 00:00:58 make a copy edit this copy and return a
- 00:01:01 new state so that the old state stays
- 00:01:03 untouched let's see how we do that
- 00:01:06 I'll make some changes here I'll create
- 00:01:08 a new constant which I'll name initial
- 00:01:11 state and this will be a JavaScript
- 00:01:15 object this initial state here well
- 00:01:19 let's say have a result of 1 so before
- 00:01:23 we had this initial state of 1 now this
- 00:01:25 is one property in the initial state
- 00:01:27 object and then it has the last values
- 00:01:31 array which is empty at the beginning
- 00:01:34 like this next in my reducer here I can
- 00:01:40 use the es6 addition of default values
- 00:01:45 or default parameters in methods to set
- 00:01:49 my state equal to initial state in the
- 00:01:52 case that no state is added or is sent
- 00:01:56 to reducer so once we dispatch actions
- 00:02:00 read acts will automatically pass the
- 00:02:02 current state to the reducer so the
- 00:02:05 initial state is then ignored but if we
- 00:02:07 first set up our store and we don't have
- 00:02:12 a state there
- 00:02:14 or yet then the initial state object
- 00:02:17 here is used to initialize the state
- 00:02:19 that's just some ESX work and if you're
- 00:02:22 not sure how all of this works well I
- 00:02:25 got a es6 video on this channel and I
- 00:02:28 even got a es6 course on udemy so you
- 00:02:30 might want to check these out if you
- 00:02:32 want to learn more links in the
- 00:02:34 description so initial state is setup
- 00:02:37 here and since I'm setting it up here I
- 00:02:39 can remove the second argument in the
- 00:02:42 create store method so now I'm only
- 00:02:44 passing the reducer because the reducer
- 00:02:47 on its own handles the initializes
- 00:02:49 initialization of the state here so far
- 00:02:53 so good we change the state to be an
- 00:02:56 object and we change the way we
- 00:02:58 initialize the state now with that
- 00:03:01 I want to use this object to then change
- 00:03:05 the state in the switch statement here
- 00:03:07 whenever we dispatch an action now I'll
- 00:03:09 leave the action the way we create them
- 00:03:12 all the actions remain the same we still
- 00:03:15 only pass values as Paulo payloads these
- 00:03:18 are not adjusted to objects there is no
- 00:03:20 need to do so because we're still only
- 00:03:22 adding 100 we're not adding an object
- 00:03:25 with 100 that's important to realize the
- 00:03:28 payload here is always just a value you
- 00:03:31 want to change in the reducer is the
- 00:03:34 place where you then have to figure out
- 00:03:36 how to correctly change the state so how
- 00:03:39 would we correctly change the state for
- 00:03:41 the add action here well we take the
- 00:03:44 state object here and we could do the
- 00:03:46 following thing we could simply stay say
- 00:03:50 that state result is equal to action
- 00:03:59 payload or is equal to old State result
- 00:04:04 plus action dot payload now if I save
- 00:04:07 this and go back to the application you
- 00:04:09 see that my store is updated do result
- 00:04:11 US 101 123 and then not a number because
- 00:04:15 the subtract action here hasn't been
- 00:04:18 updated yet so this looks fine ignore
- 00:04:22 that the last values is not updated
- 00:04:24 because I'm not implementing this yet so
- 00:04:27 the result
- 00:04:28 is updated but here's an interesting
- 00:04:30 thing even though we see result 101 here
- 00:04:35 if we expand the object we see result
- 00:04:38 123 and the reason is because we're not
- 00:04:43 doing this in an immutable way I'm
- 00:04:45 simply taking the old property and
- 00:04:48 changing the value there for all old
- 00:04:52 objects or the state in the older
- 00:04:55 objects here like the first action here
- 00:04:58 is also changed because it's one of the
- 00:05:00 same object it's the same place in the
- 00:05:02 memory and hence we don't have an
- 00:05:05 immutable approach here now why is an
- 00:05:08 immutable approach better because
- 00:05:11 currently we get no way of getting back
- 00:05:15 to an older state we can't see how our
- 00:05:18 state changed throughout the application
- 00:05:20 and therefore we're back in the world
- 00:05:23 where handling the state is a bit more
- 00:05:26 complicated because it's always hard to
- 00:05:28 know what the current state of the
- 00:05:30 application is so a better way is to not
- 00:05:34 do it this way not directly manipulate
- 00:05:37 the property but instead create a new
- 00:05:42 state here I do this by creating a new
- 00:05:46 JavaScript object so state is now a new
- 00:05:48 JavaScript object it's no longer the
- 00:05:51 state we're passing here it's a new
- 00:05:53 JavaScript object and then this
- 00:05:55 JavaScript object I want to use all the
- 00:05:58 properties of the old state now a quick
- 00:06:02 and easy way in es6 to get all the
- 00:06:06 properties of an object and add it as
- 00:06:08 properties to a new object exactly what
- 00:06:11 I want to do here is to use the spread
- 00:06:15 operator the spread operator are free
- 00:06:18 dots and here I take the state and this
- 00:06:22 may basically tells JavaScript or es6
- 00:06:26 give me all the properties of the state
- 00:06:29 object this object here which has a
- 00:06:32 result and the last value property and
- 00:06:34 add them as properties to this new
- 00:06:37 object so in this specific case here
- 00:06:41 that
- 00:06:42 exactly the same as if I would have
- 00:06:44 written state result and then state last
- 00:06:50 values but of course I would have needed
- 00:06:52 to also set is equal to result and then
- 00:06:56 here two last values like this now
- 00:07:00 that's much longer and the big problem
- 00:07:02 of course is if we change to sit here we
- 00:07:05 have to change it all over the place
- 00:07:07 here so that is a much better way to
- 00:07:10 achieve the same now of course I don't
- 00:07:12 want to simply get the old properties I
- 00:07:15 want to change the result property that
- 00:07:18 is why I now add result and set it equal
- 00:07:22 to be State result this again is the old
- 00:07:27 state here so the result of the old
- 00:07:32 state and add my payload to it action
- 00:07:36 payload that is why I simply pass the
- 00:07:40 value here as a payload and not some
- 00:07:43 kind of object because the dispatching
- 00:07:45 here or the action is not responsible
- 00:07:47 for passing the finished
- 00:07:50 new state object that's the top of the
- 00:07:52 reducer so the reducer always works with
- 00:07:55 the payloads which are types like
- 00:07:58 numbers strings may be objects of course
- 00:08:01 but never the new state so now I set
- 00:08:06 this or I created this new value
- 00:08:08 consisting of the old result property
- 00:08:11 and the payload of my action and I'm
- 00:08:15 setting this to the result property now
- 00:08:18 if you watch carefully you might think
- 00:08:21 well I'm spreading my old state object
- 00:08:25 here this old state object has a result
- 00:08:28 and has lost values and now I'm setting
- 00:08:31 result again so now I kind of created
- 00:08:34 something like this result would be
- 00:08:38 State result lost values would be State
- 00:08:43 lost values so I have result twice and
- 00:08:47 that exactly is what helps but that's no
- 00:08:51 problem because the latter result
- 00:08:54 property
- 00:08:55 so the last one I specify here overrides
- 00:08:58 all prior properties with the same name
- 00:09:01 which is the behavior I want I first
- 00:09:03 spread all the properties of my old
- 00:09:05 state and then I override the ones I
- 00:09:08 want to override now as you can see I'm
- 00:09:11 not touching the last values yet and if
- 00:09:13 my initial state would have much more
- 00:09:15 values some of them which are never
- 00:09:18 touched by an add action well then these
- 00:09:21 properties would never be overwritten in
- 00:09:23 the turn off this add action so if I
- 00:09:27 save this reload my application here you
- 00:09:30 now see store updated with results 101
- 00:09:34 and 123 but now if I expand them you see
- 00:09:38 that the value actually isn't changed
- 00:09:41 because a brand new object is created
- 00:09:43 all the time and we don't see the old
- 00:09:47 object being overwritten instead as
- 00:09:49 happened before now with that let's also
- 00:09:53 implement this for the subtraction here
- 00:09:55 so let's copy this simply subtract the
- 00:09:59 payload save this now you can see the
- 00:10:02 values being changed here again the
- 00:10:06 result and the old objects is not
- 00:10:08 touched and with that we get an
- 00:10:13 immutable way of using strings eggs of
- 00:10:18 using objects could be of using objects
- 00:10:21 as our estate now we also have this last
- 00:10:25 values array here so let's say in this
- 00:10:29 last values array here I want to store
- 00:10:31 well the value that was used in this
- 00:10:35 action so I could use my newly created
- 00:10:37 state remember I'm creating a new state
- 00:10:40 here and set last values or use this
- 00:10:43 last values here to push action dot
- 00:10:46 payload payload like this and I'll also
- 00:10:51 take this and do the same for this
- 00:10:53 abstract action I'll save this reload my
- 00:10:56 application you see everything works
- 00:10:59 here you see the array here is growing
- 00:11:01 we have an array where we have 122 and
- 00:11:05 80 Oh
- 00:11:08 again we have the same problem as before
- 00:11:11 even though we get the information that
- 00:11:14 this area has one element it actually
- 00:11:16 has free because it was changed after
- 00:11:20 the time this object was created because
- 00:11:24 I'm not doing this in an immutable way
- 00:11:26 I'm simply taking my state and then I
- 00:11:29 push a new value here but since this
- 00:11:33 last values array is the one we spread
- 00:11:37 from the old state we're always using
- 00:11:39 the same array which is stored somewhere
- 00:11:41 in memory we're not recreating it so
- 00:11:44 whilst the object the state object is
- 00:11:46 handled in an immutable way the property
- 00:11:50 this last values array here is not and
- 00:11:54 this certainly is not the way we want to
- 00:11:56 do it so we want to do this in an
- 00:11:58 immutable way – and the way to do it is
- 00:12:02 to overwrite the last values property
- 00:12:05 just like we overwrite result here and
- 00:12:08 then set this to be equal to you a new
- 00:12:12 array where again use the spread
- 00:12:15 operator to spread out the old last
- 00:12:18 values array spread operators can be
- 00:12:20 used on both arrays and objects to
- 00:12:24 either fetch out all the properties in
- 00:12:26 the case of objects or all the elements
- 00:12:28 in the case of arrays so state last
- 00:12:32 values fills this array with all the old
- 00:12:36 values and then I add a new value action
- 00:12:40 payload so that's kind of pushing in an
- 00:12:44 immutable way and I'll do the same in
- 00:12:46 the subtract case now important thing in
- 00:12:50 this case here I could of course remove
- 00:12:52 this spreading of my state object
- 00:12:54 because I'm overwriting all the
- 00:12:56 properties that exists anyways but I'm
- 00:12:59 leaving it here because in reality you
- 00:13:03 will oftentimes have a case where your
- 00:13:06 action doesn't change all the properties
- 00:13:08 of your state we might have an
- 00:13:10 additional property like let's say
- 00:13:12 username here set it equal to max and
- 00:13:15 this is never touched so therefore we
- 00:13:18 want to still spread the state and only
- 00:13:20 change the values we need to
- 00:13:22 change now if I save this and reload my
- 00:13:25 application again well we see user name
- 00:13:28 is always the same the array contains
- 00:13:30 one two and then three elements which is
- 00:13:33 of course the case in the last object
- 00:13:35 but now the first object is also correct
- 00:13:38 and at this point of time where we
- 00:13:40 changed the state for the first time we
- 00:13:43 only have the first value that was added
- 00:13:46 100 in the second place here we have 122
- 00:13:51 and then the last time we dispatch in
- 00:13:54 action we get 122 and then 80 and the
- 00:13:58 result has changed appropriately too so
- 00:14:01 that is how you handle objects and
- 00:14:03 arrays in an immutable way in your Redux
- 00:14:08 state and that is a key thing to know
- 00:14:11 and to use to make a predictable state
- 00:14:15 or to have a predictable state in your
- 00:14:17 application