Transcript for:
Ultimate Redux Course by Mosh

[Music] Welcome to My ultimate Redux course I'm mosh and I'm going to be your instructor over the next few hours in this course you will learn everything you need to know to build real complex applications with Redux we are not going to work on a dummy to-do app we're going to work on a real bug tracking application with a note backend we'll go over functional programming principles writing clean code designing complex stores middleware calling apis testing and integrating with react I'm assuming this course you know nothing about Redux and want to learn everything from scratch I will explain every line of code I write so you learn and understand all the underlying principles I Promise You by the end of this course you will know and understand Redux inside out now before we get started I want to tell you that I have a coding school at codewithmash.com where you can find plenty of courses on web and mobile development so if you want to learn more from me be sure to check out my coding school now let's jump in and get started oh so what is Redux all about well Redux is a state management library for JavaScript applications we can use it with react angular view or even vanilla JavaScript because Redux is just a state management Library it doesn't care what library we use to build user interfaces but why do we need a state management library to start with well if you have ever built an application with a complex UI you have probably come across this situation where you need to keep different parts of the UI in sync let's say the user changes some data in one part of the UI and other parts of the UI should be immediately updated to reflect the changes in more complex scenarios that data can also get updated as a result of network requests or background tasks in these situations data can flow from one part of the UI to another and change in unpredictable ways we have to write a lot of code to keep everything in sync and when something goes wrong figuring out how the data changed and where it came from becomes really complex you might even end up with an infinite Loop that is hard to break if you encountered such problems in your applications that is a sign you need a state management Library Facebook encountered this problem in 2014 and came up with an architectural pattern called flux Redux is inspired by flux but it has grown more popular due to its Simplicity and elegance another popular solution is mobx with Redux instead of scattering application state in various parts of the UI we store all the application State inside a central repository that is a single JavaScript object called the store that is a single source of Truth you can think of it as some kind of a database for the front end so with this architecture the different pieces of the UI will no longer maintain their own State instead they get what they need from the store if we need to update the data there is a single place we have to update so this immediately solves the problem of synchronizing the data across different parts of the UI but redux's architecture also makes it easy to understand how the data changes in our applications if something goes wrong we can see exactly how the data changed why when and where it came from so in a nutshell Redux centralizes our application State and makes data flow transparent and predictable now that you know what Redux is let's look at some of its benefits in action so this is a food delivery application I have built with react and Redux on the left we have food categories such as soups salads and so on we can select the category and add items to our shopping cart note that as I'm adding these items the number of items in the shopping cart gets updated immediately so let's add a bunch of items let's also add an entree now let's go to our shopping cart once again we can update the number of each item in the shopping cart as I'm doing this the total price for this item for the cart as well as the number of items in the shopping cart get updated in real time so all the data in my application is in sync because we have a single store where we are storing our application State let me show you where it is this is Redux Dev tools a powerful tool for debugging Redux applications it's an extension to Chrome so over here you can see my entire application State 3 in one place so we have these entities we have our shopping cart we have our food categories and food items this auth object over here represents the current user so we have all the information about the current user and their authentication token we also have this UI property which includes some UI State now let me show you something powerful on the left side you can see all the actions that I have performed in this application so you can see I've added a bunch of items to my shopping cart now if I remove the first item green lentil soup you can see we have a new action here item removed if you select this action we can see the data associated with this action so over here I try to remove the product with id5 now let me show you something very cool I'm going to put this on the left side so you can see clearly let's jump to one of the previous actions the UI got updated immediately so we can go back to any of these previous actions and restore the UI in that state this is called time travel debugging we can also save the entire application state in a single file and reload the application from it later how many times have you got a call from your client or your boss telling you that a feature in your application is not working in these situations we have to ask them how did this happen tell me the exact steps that you followed then we have to repeat all those steps to reproduce the bug now every time we change our code our application gets reloaded and we have to follow those steps over and over this is very time consuming with Redux we don't have to do this anymore there's actually a tool called log rocket that gives you an always-on Redux Dev Tools in production for every one of your users so if a user encounters a problem you can reload the application in the same state as the user and see what was going on it's very powerful another benefit of Redux is that it allows you to cash or preserve paid State let me show you what I mean so over here note that when I refresh the page you're going to see a loading indicator for three seconds indicating a slow connection so look refresh here's our loader now the menu appears okay now if we navigate away from this page and then come back to it the menu is already there we don't have to re-download it from the server because our entire application state is available on the client inside a single JavaScript object also I can select a filter here let's say soups and sort the menu by price once again if we navigate away and then come back our menu is in its previous state so let's quickly recap Redux makes State changes predictable and transparent we can easily see what exactly is going on and how the application State changes in response to every action the second benefit of Redux is that these centralizes our application state so all the data our application needs is stored in a single place that is accessible by all parts of the UI with Redux we can also easily debug our applications we can easily cache or preserve paid State and Implement undo or redo features so if your application needs these features you may want to consider Redux the great thing about Redux is that it works with any libraries for building uis you can use it with react angular Ember view even vanilla JavaScript plus we have a large and growing ecosystem of add-ons so these are all the great things about Redux but all these great things come at a cost redox introduces some indirection and complexity in your code this is partly because Redux is based on on functional programming principles and a lot of developers are not familiar with this concept but don't worry I'm going to teach you the basics of functional programming very soon another problem with Redux is that Redux code tends to be verbose you have to write some boilerplate code to get things done this is one of the main complaints about Redux so in this course first I'm going to show you the traditional way of writing Redux code which has a lot of boilerplate but later on I will show you the modern way of building Redux applications you're going to learn how to write clean and concise Redux code free of boilerplate so with all that is Redux for your dot we'll talk about that next if you have seen any of my courses before you've probably seen this guy his name is John Smith it's kind of arrogant and opinionated about everything so he says that he uses Redux in every project and so should you well I tend to disagree for every project or app you need to understand what problem you're trying to solve what your constraints are and what solution optimally solves the problem according to those constraints there is no such a thing as one size fits all in software engineering if you're on a tight budget if you're building a small to medium-sized app with fairly simple UI and data flow if the data doesn't change in your app or if you simply fetch the data on every page load and render it statically on the page redox is probably not the right tool for you it's just going to complicate things and slow you down without giving you much value so don't use Redux or any other tools because they're popular or someone told you to always think about your needs and the kind of app you're building now John argues that you should always use Redux right from the get-go because their State Management problem will get messy sooner or later so it's better to have the right foundation in the project well that reminds me of the old proverb if all you have is a hammer everything looks like a nail developers like John are often used to a certain way of building apps they solve every problem using the same solution and honestly I think that's just basic human nature we don't want to constantly think and figure things out we like to be an autopilot but if you want to be a real software engineer you need a different kind of attitude you need to be an active Problem Solver so the bottom line Redux is great it provides a number of benefits at the cost of extra complexity in your code base you will see this as we go through this course for every app you need to think about all the pros and cons of Redux and see if it's really the right tool for you or not in fact down every month the creator of Redux once said you might not need Redux this is a great blog post to read in your spare time so at the end of the day I encourage you to watch this course to the end because it helps you see what Redux is all about and whether it's the right tool for your next project or not also keep in mind that almost 60 percent of react projects are built with Redux so if you're a react developer chances are the next job or project you get is based on Redux so you need to know how Redux code works and how to maintain it and that's what you're going to learn in this course oh if you look below this video you're going to find the starter project for this course so simply open this folder with vs code or your favorite code editor now all you have to do is to open up a terminal window install the dependencies and start the project using npm so npm install all right all of our dependencies are installed so now let's start the project with npm start Now open up your browser and head over to localhost Port 9000 you should see the hello world message now let me give you a quick overview of what we have in this project so take a look at package.json here we have three development dependencies and they're all related to webpack in case you are not familiar with webpack it's actually a module bundler for JavaScript so we can split our JavaScript code into multiple files and have webpack combine them into a bundle we also have webpack development server which is a very lightweight development web server now over here you can see the configuration for webpack this is pretty standard nothing fancy here so we're telling webpack that the entry point to our project is this file index.js that is located in the source folder now webpack is going to start from here it's going to get all of our JavaScript files and then combine them into a file called app.js which is going to reside in this folder this which is short for distributable and here's the configuration for our development server so we are telling webpack to launch our application from this folder on Port 9000 pretty straightforward before we dive in let me give you a quick overview of how I've structured this course so you can get the most out of it Redux is based on functional programming principles a lot of people find Redux confusing because they are not familiar with this functional programming Concepts so the next section is all about functional programming in JavaScript we'll be talking about Concepts such as higher order functions composition occurring immutability and so on the following section is all about the fundamentals of Redux in this section you will see all the building blocks of Redux in action we'll be talking about reducers actions action creators and so on now Redux itself is a very simple Library so in the following section I'm going to show you how to implement Redux from scratch yourself this helps you gain a better understanding of this Library so it will no longer be a mystery to you you will know exactly how everything works next we'll talk about debug and Redux applications I will show you various tools available to you and how to use them to debug your Redux applications now some of the most common complaints about Redux is that it involves too much code too much boilerplate and that Redux code is ugly and unmaintainable so in the following section I will show you tons of techniques to write clean concise and beautiful Redux code then we're going to talk about designing a Redux store we'll talk about some patterns and techniques that you need to know for building real complex applications then we're going to talk about middleware this is one of the areas that a lot of people find confusing so I'm going to make it super simple for you next we're going to talk about calling apis I've seen a lot of bad code when it comes to calling apis a lot of repetition so in this section I'm going to show you a very cool technique for calling apis we'll also talk about some other concerns such as loading indicators and caching the following section is about testing again I've seen a lot of bad practices when it comes to testing a lot of people blindly write tests and feel proud but you need to learn how to rate good tests not just tests so in this section I will show you the proper way to test Redux code finally in the last section we'll talk about integrating Redux into your reactant applications I'm going to show you both the Old and the new way of connecting your components to a Redux store so there's a lot we're going to cover and by the end of this course you're going to master Redux that's my promise to you so I'll see you in the next section Redux is built on top of functional programming principles which is foreign to a lot of developers if you have tried Redux I'm very confused that's probably because you didn't have a good background in functional programming so in this section we're going to cover the essential functional programming Concepts I highly encourage you to watch this section to the end because understanding these Concepts is crucial to build Redux applications so let's jump in and get started so what is functional programming well functional programming is one of the many programming paradigms or styles of programming you have probably heard of object-oriented programming that's another popular programming Paradigm or style of programming each of these paradigms has certain rules about how you should structure your code to solve problems functional programming was invented in the 1950s but it has become quite trendy over the past few years in a nutshell functional programming is about decomposing a problem into a bunch of small and reusable functions that take some input and return a result they don't mutate or change data with this structure we can compose these functions to build more complex functions now what are the benefits well these small functions tend to be more concise easier to debug easier to test and more scalable because we can run many function calls in parallel and take advantage of multiple cores of a CPU so these are the reasons why functional programming has gained a lot of popular already over the past few years now there are languages that are specifically designed for functional programming such as closure and Haskell JavaScript is a multi-paradigm programming language it's not a pure functional language so it has some caveats that you need to be aware of but we can still apply functional programming principles in JavaScript and that's what I'm going to show you throughout the rest of this section alright our first lesson here is going to be a JavaScript refresher about functions chances are you know what I'm gonna show you in this lesson so please be patient with me I want to make sure you've got the fundamentals right before we move on to more complex topics so in JavaScript functions are first class citizens which means we can treat them just like any other variables we can assign them to a variable we can pass them as arguments and return them from other functions let me show you so in our starter project I'm going to write all the code in this file index.js so let's declare a function called say hello that returns and string hello world as always now let's declare a variable call FN we can set this to a number or a Boolean or a string but we can also set it to a function say hello note that I'm not calling this function because if we call it we get its return value which is a string we don't want to call the function we simply want to pass a reference to it so functions are first-class citizens in JavaScript we can treat them like any other type of objects nothing special about them okay now FN is an alias for say hello so we can call it just like calling the say hello function the result is exactly the same we'll get a string back okay now we can also pass a function as an argument to another function so let's declare another function called grid which takes a function for generating a message now here we can do a concept.log and pass the return value of this function so our grid function takes a function as a parameter and calls it over here okay now we can call grid and pass a reference to the say hello function once again I'm not calling this function I'm simply passing a reference to it okay so in JavaScript we can assign a function to a variable we can pass it as an argument we can also return it from another function so let's get rid of this code in our say hello function instead of returning a string we can return a function in this case an anonymous function because this function does not have a name now inside this function we're going to return hello world with this structure if we call say hello we're going to get a function back okay that is this Anonymous function over here now we can call this function and get our message now you might be wondering what is the purpose of this why do we want to return a function here instead of a regular string well this is a very powerful technique and it has a lot of applications in the real world you're going to see that soon all I want you to understand now is that in JavaScript functions are first class citizens we can treat them like any other variables foreign in the last lesson you learned that in JavaScript and other functional programming languages we can pass a function as an argument and return it now in this example these two functions create and say hello these functions have a special name in functional programming they're called higher order functions so a higher order function is a function that takes a function as an argument or returns it or both so instead of working on strings numbers or booleans it goes higher to operate on functions this is the reason why we call them higher order functions the chances are you have worked with these higher order functions before without being aware of it let me show you so I'm going to declare an array of numbers one two three now we can call numbers.map map is an example of a higher order function because it takes a function as an argument so here we can pass a function like this number goes to number times two so we take each number and multiply it by two another example of a higher order function in JavaScript is the set timeout function so we can call set timeout here we should pass a function as an argument let's say we want to do a console.log of hello after one second so set timeout is a higher order function because it takes a function as an argument foreign functional programming is to write a bunch of small and reusable functions and then compose them to build more complex functions for solving real-world problems here's a real example let's say we have a variable called input and we set it to JavaScript now let's add some padding around this let's say we want to get the input trim it and then wrap it inside a div element so with declare another variable here we add the opening element next we add our trimmed input and finally the closing element not bad it works this is a non-functional style of code now let me show you how to solve this problem using functional programming techniques so what are the two steps that we need to follow here first we need to trim the string and then we need to wrap it inside a div element so we can Implement each step using a small reusable function so I can declare a function called trim that takes a string and Returns the trimmed string okay here I'm using const because I don't want to reassign this function okay now similarly we can create another function wrap and div that takes a string it doesn't care if the string is trimmed or not it only wraps the string inside a div element so here we can add an expression like this div plus SDR plus slash Dev or we can use a template string that is cleaner and more concise so instead of using quotes we use the back the character and here we Define a template so we add our div element now in the middle we want to render the string dynamically so we add a dollar sign and wrap it with braces and with this we can render this dynamically okay so now we have two small and reusable functions these functions as you can tell are very easy to test all we have to do is to give them an input and then observe the result very simple now what do we want to do here we have this input right we want to trim it first so we call the trim function and pass the input the trim function is going to return the trim string so we can pass that as an argument to our second function wrap and div there you go so we get the result and this is what we call function composition in functional programming now we could take this to the next level we can also create another function for converting a string to lowercase so two lowercase once again this function takes a string and returns the string and lowercase now we can take the output of the trim function and pass it to two lowercase so this is another example of composition now we have a couple of tiny problems here the first problem is that we have to read this expression from right to left so we have an input then we need to trim it next we need to convert it to lowercase and then wrap it in div that's one problem the other problem is all these parenthesis here as we work with more complex problems we'll end up with so many parentheses I'm going to show you how to solve these problems in the next lesson foreign I'm going to show you how to use low Dash to simplify the code we wrote in the last video so in case you're not familiar with low Dash it's basically a very popular utility library for JavaScript it also has a package with a lot of functions for functional programming I'm going to show you how to use them in this lesson so back in our project open up a terminal window and install low Dash all right beautiful now on the top we're going to import two functions from low dash one of them is compose the other is pipe we're going to import them from low Dash slash FP as in short for functional programming so all these utility functions for functional programming are defined in this package now with these two functions we can get rid of all these unnecessary parenthesis over here let me show you so first I'm going to use the compose function we call compose and give it three arguments wrapping div to a lowercase and trim once again note that I'm not calling any of these functions I'm simply passing a reference to that so compose is another example of a higher order function because it takes a bunch of functions as arguments and returns a new function that is the composition of all these functions so it's a higher order function now we can get the return value which is a function and store it and a constant called transform then we can call transform and give it the input so with the compose function we no longer need to do this nest.function cause our code is cleaner we don't have all these parentheses polluting the code there is just one tiny problem here that is the order of our operations so once again we have to read this code from right to left to solve this problem we can use the pipe function so we call pipe and list our functions in the order we want to apply them so first we're going to trim the input then we're going to convert it to lowercase and finally we're going to wrap it in a div so we no longer need this ugly code with all these parenthesis delete good in this lesson I'm going to show you a powerful functional programming technique called curing I like what you might think this has nothing to do with food this is named after this guy Haskell Curry so back to the problem from the last video Let's extend this program and create a function for wrapping a string inside a span element so over here we create a new function wrap in Span and let me copy this code from here and then replace div with span pretty straightforward yeah there is a problem in this code we have a bit of duplication these two expressions look very similar the only difference they have is in the type of element it would be nice if we could parameterize this function so instead of wrapping span let's call it wrap and give it two parameters type and input string then instead of this man we're going to render the type okay now let's get rid of wrap and div and instead use our new function wrap finally let's log the return value of the transform function on the console save the changes so here's what we get JavaScript undefined that doesn't make sense here's Arisa this Pi function essentially builds a pipeline the output of each function ends up being the input of the next function so what is the output of the two lowercase function it's our input string in lowercase right so that gets passed to a wrap function now this function has two parameters type and input string so our input string in lowercase gets passed as the type argument and the second argument becomes undefined that is the reason why we get this result now what if you call wrap and pass div as the type of element let's save the changes back in the console we get this error expected a function because every argument to the pi function has to be a function in this case we're calling the wrap function and give it div as the type of element so this is going to return a string we cannot pass a string in the pi function because we cannot build a pipeline with a bunch of functions and a string it doesn't make sense so here's the problem you're facing we have a function with two parameters but what we need in this pipeline is a function with a single parameter and that's the problem that occurring solves let me show you so I've created a separate file called occurring let's study current and isolation and then we'll come back to our main file so let's say we have a function for adding two numbers A and B here we turn a and b curing is a technique that allows us to take a function that has an argument and convert it to a function that has a single argument so to apply querying here we get rid of B as the second parameter and instead of returning this expression we're going to return a function that takes a parameter called B and then inside this function we're going to return a plus b so when we call the add function let's say add one this is going to return a function let's call it add one so every time we call this function and give it a value it's going to add 1 to it okay now in this case we don't need to store this function in this constant we can call add one we know that this returns a function so we can call that function and pass our second argument so with current instead of separating our arguments with comma we separate them using parenthesis but what matters here is that we have a function with a single parameter now we can also rewrite this function using an error function so let's declare a function called add to now this function should take a parameter called a and return a new function so a goes to now here we should return a function that takes a parameter called B so B goes to and returns this expression so once again instead of separating our parameters using a comma Like A and B goes to a plus b we are separating them using arrows this is the result of carrying a function now let's apply this technique in our main program so the problem we have here is that the wrap function takes two parameters we want to apply current here so we end up with a function with a single parameter so to separate these parameters instead of a comma we're going to use an arrow so we don't need parenthesis because we have a single parameter type goes to string goes to this expression this is our current function now here's the interesting part when we call wrap and pass div we get a function instead of a string so we can pass that function as another step in our pipeline let's save the changes and here's the final result so we wrapped JavaScript in a div element with this new implementation we can replace div with a span or any other elements save the changes there you go so we don't have to create so many functions for creating HTML elements hey Mash here thank you for watching my Redux tutorial this tutorial you've been watching is actually the first hour of my complete Redux course that is 6 hours long so if you enjoyed this tutorial and want to learn more I highly encourage you to take the full course because it goes Way Beyond this tutorial if you enroll you will also receive a certificate of completion that you can add to your resume if you're interested I'll put the link down below another important Concept in functional programming is pure functions we say a function is pure if every time we call it n give it the same argument it always returns the same result let's look at a few examples look at this function do you think this function is pure or not it's not because every time we call it this math.random method generates a new value so the result of this function is going to change in contrast this function is pure because every time we call it and give it one we always get 2. so in pure functions we cannot use random values we cannot use the current date time because again this will change we cannot read or change Global State like Dom elements files databases and so on because if you rely on global state or change it this can affect the result of our Pure functions now you might say but Marsh how are we going to update our Dom elements or our database well in practice not everything has to be pure at least when practicing functional programming with JavaScript in Redux we have special functions called reducers we'll talk about them in the next section when building redox applications we have to make sure that our reducers are pure other functions in our application can be impure that's not the end of the world now in pure functions we cannot mutate our parameters because if we do so again the result of a pure function can change let's look at a few more examples so this function takes the H of someone and Compares it with minimum age as you can see minimum age is not defined here so it's a global variable now if you rely on This Global variable to see if someone is eligible or not the result of this function can change in the future so if somewhere else we change the minimum age from 18 to 21 this function is going to return something different to make this function pure we have to pass minimum age as a parameter so everything this function needs should be specified in its parameter list now what are the benefits of pure functions well the first benefit is that these functions are self-documenting because everything a function needs is clearly specified here now this makes these functions easier to test because we don't have to set some Global State prior to testing these functions also because we don't use Global state or change it we can run these functions in parallel and finally another benefit of these functions is that they're cachable for example if we call this function and give it two arguments like one and two and we know that this always returns three we can store the result in the cache and use it in the future this is useful in functions that have intensive computations so if you know for sure that they produce the same result or the same arguments we can optimize them by reading the result from a cache so these are the benefits of pure functions in the last video I told you that pure functions cannot change or mutate their arguments the concept that goes hand in hand with pure functions is immutability which basically means once we create an object we cannot change or mutate it if you want to change that object you have to take a copy first and then change that copy for example strings in JavaScript and in most programming languages are immutable so if you have a string and then try to convert it to uppercase we get a new string the original string is not affected in contrast if you have an object we can change or mutate that object directly so in JavaScript objects on arrays are not immutable and that's why I told you that JavaScript is not a pure functional programming language in pure functional languages we cannot mutate data period but in JavaScript we can mutate objects on arrays because JavaScript was not designed to be a functional language it's a multi-paradigm language but we can still apply functional programming principles when writing JavaScript code now what about the cost keyword well this is a common misconception when you use const you're not creating an immutable object so we can declare book as a constant and then change its title property with const we cannot reassign book to a different object so const prevents reassignment okay now what are the benefits of immutability well the first benefit is that it makes our applications more predictable if we call a function and pass an object to it we know that object is not going to get changed so there are no surprises down the road the second benefit of immutability which is kind of specific to react and Redux kind of applications is that it makes it faster to detect changes so you know that react needs to know when the state is changed so it can trigger re-rendering for example let's say we have a book object stored in the memory location 100. now if you follow immutability to change a property of this object we have to create a new object this object is going to be stored in a different location in memory let's say 200. now react can quickly tell if an object is modified because it Compares these objects by the references it's like comparing 100 with 200. this is a very fast operation in contrast if we don't use immutability react has to compare every property of an object to see if it's changed so immutability makes change detection faster and the third benefit of immutability is concurrency if we know that a function does not mutate data we know that we can safely run this function in parallel it's not going to change something in memory that's going to mess up the state of the system as a whole so doesn't mean object mutation is bad and we should always favor immutability well if you ask John Smith he would say that's exactly right but in my opinion every approach every technique has its own uses pros and cons anyone telling you that one technique is objectively good or bad in all situations is selling you something so we talked about the benefits of immutability but these benefits are not free of cost there is a potential performance cost to immutability because every time we change an object all the values should be copied to the new object however this would only be an issue if you're dealing with a large number of objects let's say several thousands or hundreds of thousands of objects if you're dealing with a few objects that's not going to be an issue another problem with immutability is that copying objects can also cause memory overhead but we have immutability libraries out there that reduce these overheads as much as possible they use a technique called structural sharing so if some values are common between two objects they are not copied across they're shared but talk about this Library soon so the bottom line is if you're building applications with Redux you should not mutate data because that's a fundamental principle in Redux outside of Redux you can do whatever you want so now that you understand what immutability is and why it's important let's see how we can practice it in JavaScript so let me show you how you can practice immutability when working with objects so here we have a personal object with a name property now if you want to update this object we are not supposed to set the name property directly we should take a copy first and then update the copy there are basically two ways to do this in JavaScript one way is to use the object that assign method with this method we can copy the content of an object to another object so as a first argument we pass an empty object then we pass our personal object so this is going to copy all the properties of this object into this empty object optionally as a third argument we can supply an object with updated properties for example if you want to change the name property yeah that here let's set this to Bob we can also add additional properties let's say we can set H to 30. now this method is going to return a new object so let's call that updated and then log it on the console so we have this object with name set to Bob and age 30. so object.assign is one way to solve this problem but there is a better way we can use the spread operator so I'm going to set up data to an empty object now here we want to copy all the properties of the person object so we type dot dot dot person this is what we call the spread operator now that we've copied all the properties of the person object we can supply any additional properties so if you want to update the name you can pass it here in this case the second name property is going to overwrite the name property that we copied from the person object okay now save the changes and here's our updated person so I personally prefer the spread operator syntax because it's more concise now one thing you need to be aware of when using the spread operator or object of assignment is that both these methods do a shallow copy so you have to be careful when working with nest.objects for example let's add an address property here address we set it to an object with two properties Country USA and City let's say San Francisco now we're copying this person and changing his name now let's see what happens if we type updated the address that City we set it to New York and then log the original person object see what happens so save the changes so our original personal object his name was John now look at his address it's updated to New York because this spread operator does a shallow copy in this case this address property is set to an object the problem we have here is that both the person and updated objects have the same address this is the same address object in memory so if you change the address through one reference like updated it will apply to the other reference to solve this problem we have to do a deep copy so let me show you first we copy all the properties of the personal object then we add the address property we set it to a new object because we don't want to use the same address object associated with our original person object okay so we set it to a new object in this object first we should copy all the properties of person that address and then if we want we can change one of its properties let's say we can change the City to New York okay now we don't hit this line over here let's save the changes so if you log the original percent you can see its address is not modified so when working with nest.objects we have to do a deep copy now as you can see this approach is a little bit verbose the more nesting we have the more variables our code is going to be this is why we have libraries specifically made for immutability we're going to talk about them later in this section oh in this lesson I'm going to show you how to practice immutability when working with arrays so here we have an array of three numbers let's look at three different scenarios adding an item to this array removing an item and updating an existing item so for adding once again we can use the object spread operator so I'm going to declare a new constant called added and set it to a new array now first we want to copy all the elements in the numbers array and then we want to add a new element at the end this is how we can achieve this if you want to put this element at the beginning we can do it like this very easy what if you want to put it at a specific position let's say just before two well first we need to find the index of two so index we set it to numbers that index of 2. now we're going to create a new array first we have to copy all the items before two to do that we use numbers the slice we given that you start index that is zero this is going to return a new array with all the elements starting from index 0 up to the element at this index but excluding this element now as I told you the slice method returns a new array so we have to spread that array otherwise we'll end up with an array of arrays okay so we copy all the items before two now we add our new item let's say four and then we need to copy all the items starting from 2 all the way to the end of the array so once again we're going to use numbers dot slice as the start index we're going to pass index now because this returns an array we have to spread that array okay let's do a console.log so cancel the log of added and here's the result 1 4 2 and 3. now what about removing well this is very easy let's say we want to remove two so we use the filter method here we pass a function so n goes to we want to return all the elements except two so n not equal to 2. this returns a new array let's store it and this constant call removed and do a console.log so 2 is gone now what about updating this is fairly easy as well so we call the map method on our numbers array here we pass a function n goes to let's say we want to replace 2 with 20. so if n equals 2 then we're going to return 20 otherwise we'll return n now if we had an array of objects here instead of just returning some number we would have to copy that object so we would have to use the spread operator to take a full copy of that object okay so let's store the result in updata and then do a console.log take a look so we replaced 2 with 20. now if you forget any of these patterns don't worry I'm going to include all the source code that I'm writing throughout this course in a separate project that should be available in the zip file that you downloaded at the beginning so let me show you what I've done here I've created a folder called functional and all the code that I've written throughout this section is available in this folder for example we have examples of current we have patterns for updating objects so we can always come back to the source code if you forget something foreign does not prevent object mutations because it's not a pure functional programming language to work around this we have to use libraries that offer real immutable data structures there are tons of laborers out there but the most popular options are immutable imer and Mari immutable or immutable JS is developed by Facebook and it's a very popular Library it gives you a bunch of immutable data structures such as a map or a list but there are a number of problems with this Library I'm going to talk about them in the next video Emer is a neural library that is developed by the creator of mobx it's becoming very trendy and a lot of people including myself love it unlike emulable.js email doesn't give you any immutable data structures so it allows you to work with the plain old JavaScript objects now Mari honestly I've never worked with it but I've heard it's popular at the end of the day the library you choose is entirely up to you these are just tools different people love different tools next I'm going to show you how to work with immutable Js in this lesson I'm going to give you a quick tour of immutable JS so here we have a basic JavaScript code we have a book object with a title property we have a function called publish it gets a book object and set its published properties true next we call this function and then log this book on the console pretty straightforward now when practicing functional programming we don't want to muted objects so this is where we can use immutable.js immutable JS provides a bunch of immutable data structures so instead of using a plain JavaScript object we're going to use one of the data structures provided by immutable.js so first open up your terminal window and run npm install immutable okay so I'm using immutable version 4.0 now back to this code on the top we need to import the map function from the immutable Library with this map function we can create a map or hash map that's like a regular JavaScript object it's a container for key value pairs but this map object that we get from this library is immutable so now instead of using this plain JavaScript object we're going to call the map function to get a map object now let me temporarily comment out this code so we create a map object and log it on the console take a look so this is what we get this is not a regular book object it has a bunch of weird properties like size root owner ID and so on so this is the first problem with this Library if you want to log the title of a book we cannot access the title property using the dot or bracket notation we have to call the get method get title save the changes there you go so the first problem of this library is that we have to learn a whole new API now this API is not that complex we can learn it pretty quickly but in my opinion the main problem is that it's hard to integrate this with other libraries that expect plain JavaScript objects every time we need to work with plain JavaScript objects we have to call the 2js method so this returns a plain JavaScript object now let's bring this code back in so when publishing a book you want to set its published property to true to do this using immutable we have to call the set method so set is published to true now this is not going to modify the original book object it's going to return a new object because all these map objects are immutable like strings in JavaScript so here we have to return the result we've published a book and then we can reassign the book variable and then we can convert it to a plain JavaScript object and log it on the console take a look so here's the result so here's immutable.js in action as you can see once you start using it it gets spread out everywhere in your code base everywhere you have to use these Getters and Setters or convert immutable data structures to plane JavaScript objects that is why I personally prefer immer we're going to talk about that next foreign ER as you can see on npm Trends Emer has gained a lot of popularity and is almost as popular as immutable JS so this Orange Line represents immutable and the blue line represents imma so in our terminal window let's install imer alright now we have the same code that we had in the last video so here we are mutating this book object we don't want to do that let's see how we can solve this problem using immer so on the top we import the prettiest function from imer make sure to import it from Emer before I was recording this video I made a mistake and imported it from immutable the immutable Library does not have this produce function okay so in our polish function we are not going to mutate the book object instead we're going to call the prettiest function and give it two arguments the first argument is our book object over here this is what we call the inertial state then we're going to pass a function that specifies our mutations so this function is going to take a book object to differentiate let's call that draft book that goes to a block of code now in this block we can write mutating code so we can write draft book dot is published equals true however when following this pattern this book object is not going to get modified because this draft book is actually a proxy that records all the changes we are making to this initial book object so this produce function is going to take a copy of this object and apply all the changes we are doing here now what is beautiful about Emer is that our code looks familiar to us so we are writing code as if we are mutating an object but our object is not going to get mutated this is much better than using the spread operator because you saw that the spread operator can get kind of nasty when we're dealing with nested objects we have to do a lot of cloning with Mr we don't have to worry about any of this we simply follow this pattern and write code in a familiar style now this produce function is going to return the updated object so we're going to return it from our publish function so this publish takes a book and returns a new book let's call that updated and then we can log both these objects on the console take a look so here's our original book object as you can see it's not modified and here's the updated book object now that you have learned the fundamentals of functional programming you're ready to learn Redux so in this section we'll be talking about the Core Concepts in Redux we'll start off by talking about the Redux architecture then I'll show you the steps that you need to follow to build an application with Redux you will see all these steps in action using a real project so let's jump in and get started oh earlier I told you that with Redux we store our application State inside a single JavaScript object called the store this object is the single source of Truth for our application State and is accessible by all parts of the UI for example in an e-commerce app our store can have properties like the list of categories products shopping cart the current user and so on what we have in the store is entirely up to us Redux has no opinion about it we can use arrays objects numbers booleans essentially anything that represents the data that our application needs to function now we cannot directly modify or mutate the store because Redux is built on top of functional programming principles in the last section I told you that in functional programming we do not mutate state so we cannot write code like this because our store is an immutable object so to update it we should create a function that takes the store as an argument and Returns the updated store so in this function we should either use the spread operator to create a copy of the store or use one of the immutability libraries that we talked about in the last section like immutable JS or immer now this function is called a reducer I know the name is a bit weird and a lot of people have complained about it but let's not worry about it for now all that matters is that a reducer is a function that takes the current instance of the store and Returns the updated store now here's a question how does the reducer know what properties in the store it should update should it update the shopping cart or the current user or the list of products so we need another building block called an action an action is just a plain JavaScript object that describes what just happened examples are the user logged in or logged out or added an item to a shopping cart and so on these are the events that can happen in our application so we should give this reducer an action as the second parameter now based on the type of the action the reducer will know what properties of the state to update now doesn't mean that all the updates are going to happen inside a single function or a single reducer no this is just a simplified example in a real app our store can have many slices for example here we have four slices categories products the shopping cart and the current user each reducer will be responsible for updating a specific slice of the store as a metaphor think of an organization with multiple departments each department should have a manager that is responsible for their own department they don't have to worry about the other departments so these are the three building blocks and Redux applications we have the store which is a single JavaScript object that includes our application State we have actions which are plain JavaScript objects that represent what just happened it would be nicer if they were called events because in programming an event represents what just happened we also have one or more reducers each responsible for updating a slice of the store you can think of these reducers as event handlers or processors I think the reason they are not called event handlers is that could often even handlers are associated with object mutation which is something we don't do in Redux users are pure functions so they don't touch Global State they don't mutate their arguments and they don't have any side effects they just get the current store instance and return the updated one now how do these building blocks work together well when the user performs an action let's say they add an item to their shopping cart we create an action object and dispatch it the store object has a dispatch method that takes an action it will then forward this action to the reducer so we do not call the reducer directly we just work with the store the store is in charge of calling the reducer okay the reducer computes the new state and returns it next the store will set the state internally and then notify the UI components about the update these UI components will then pull out the updated data and refresh themselves you're going to see all these interactions in a few minutes now you might be wondering why redox is designed this way why do we need this building blocks why do we need to dispatch actions well this dispatch is like an entry point to our store so by dispatching actions we are essentially sending every action through the same entry point so we have a central place where we can control what should happen every time the user performs an action this allows us to do some really cool things for example we can log every action this is how Redux Dev tools works it shows every action that has been dispatched and how this date has changed we can also easily Implement undo and redo mechanisms so that's the idea over the next few videos I'm going to show you all these building blocks in action foreign now we're ready to build our first Redux application we're going to build a bug Tracker app using Redux so on the UI we're going to have a text box for entering information about a bug we just discovered we can add this block to a list then we can remove a bug we can mark it as resolved we can change the status to in progress and so on now in this section we're not going to spend any time on the UI because Redux is about State Management so we want to focus on Redux we don't want to get distracted with all the complexities of building user interfaces we'll talk about the UI later when we talk about integrating Redux with react okay so now let's look at the four steps that you need to follow when you want to build a Redux application first you need to design the store you need to decide what you want to keep in the store next you need to define the actions what are the actions that the user can perform in this application next you create one or more reducers these reducers take an action and return the updated State and finally you need to set up the store based on your reducer over the next few lessons we're going to look at each of these steps in detail now before we get started we need to add Redux to our project so in the terminal window we type npm install Redux I'm going to use the latest version which is version 4.0 the chances are in the future there is a newer version available what I'm going to show you in this course I have confidence that's going to work with the future versions of Redux but to be on the safe side I highly encourage you to use the same version I'm using here so version 4.0 all right Redux is installed so next we'll talk about designing the store the first step in building a Redux application is designing the store we need to decide what we want to keep in the store so for a buck tracking application like this what kind of state do we need we need to maintain the list of books so this is the simplest structure we can come up with we can have an array of bug objects every bug object can have properties like ID description and result which is initially set to false this is the simplest structure we can come up with now in a more real life application our store would probably look like this so instead of an array we're going to have an object with multiple properties so this object has a property called Bugs this is where we have our list of bugs we can have another property called current user this can initially be a null when the user logs in we're going to set this to an object so in this example our store has two slices one slice for the list of bugs and another slice for the current user and that means we're going to have two different reducers now in this section we don't want to worry about all these little details we want to focus on the simple structure that allows us to study Redux and see all its building blocks in action so we're going to go with this structure later in the course as our application develops we can refactor this structure and turn it into something more like this so we have completed the first step to build a Redux application now the second step is defining the actions what are some of the actions that a user can perform in our bug tracking application well they can add a bug they can Market bug as resolved and delete a bug now in a real live application we could have many other types of actions for example the user can change the status of a book they can filter the list of books they can change the sort order and so on for now let's just focus on these actions earlier I told you that an action is just a plain JavaScript object that describes what just happened here's an example you have an object with two properties type and description type is the only property that Redux expects in your action objects so if you don't have this type property Redux is going to complain now here we're using a string as the value of the type property but you can use any other type that is serializable which means we can store it on the disk why because Redux is built on this principle that we should be able to store the state of our application on disk and reload from it later strengths are serializable we could also use a number here but the problem with numbers is that they are not descriptive we don't want to write code and compare the type of an action with let's say 124. someone else reading our code would wonder what is 124 they are not descriptive also when you look at the action history in Redux Dev tools we don't want to see a bunch of numbers you want to see a description of what has happened that is why we use strings now here I've used uppercase letters and I've separated these words using an underscore this is a common convention in Redux code but you don't have to follow it if you don't want to Redux as the library doesn't care you can use any naming convention that you prefer I personally prefer a different convention like bug added so I'm using a past tense because an action represents what just happened now here we have another property called description so this is the data associated with this action when the user types something in the text box to add a bug you store that value in the description property in a real application we could have a complex form with many fields the user can specify who reported this bug what is the severity and so on in that case we will store all those extra attributes in this object now earlier I told you that Redux was inspired by flux which is an architectural pattern and a library built by Facebook in flux actions have a slightly different structure so they have two properties type and payload payload is an object that contains all the data about an action you don't have to follow this structure in Redux because Redux doesn't care but I personally prefer this structure because it gives my actions a common and consistent structure let's look at another example here we have an action for removing a bug so the type is bug removed and in the payload we have the ID of the bug what is important here is that the payload contains the minimum information we need about an action so if you're removing a bug we don't need to store the Box description or the date that occurred and so on all we need to identify a bug is its ID so now that we have an idea about our actions next we're going to build our reducer now we're ready to create our first reducer so here in the source folder let's add a new file called reducer.js as I told you before a reducer is a function with two parameters the current state and an action the job of this reducer is to return the new state based on this action so here's an example if action.type equals bug added then you're going to return the new state the earlier we decided to use a simple array to represent our store an array of books so if the user adds a book we want to return a new array in this array first we want to copy all the bugs in the current state so here we are using the spread operator and then we add a new bug object here this object should have a few properties like ID description and result so we set description to action that payload the description and we said resolved to false now for the ID we need to have some kind of counter so I'm going to declare a variable here last ID and initialize it to zero every time we add a book we're going to increment last ID first and then use it as the value of the ID property there is something I want you to pay attention to here the payload of the action should contain the minimum information we need to update our system so in the case of adding a bug we don't want to pass the ID or result properties because the minimum information we need for adding a bug is the description of the bug so everything else should be computed here in the reducer because this is where we Implement our business logic okay also here I'm using the spread operator to copy this array we don't have to do this we can use one of the immutability libraries like immutable JS or immer we'll use them later in the course for now I just want to show you the plain Redux code because that's what you see in most projects so here's a case for adding a book so after a return statement we can have else if action the type equals bug removed now here we want to return a new array that contains all the bugs except the bug with the given ID so I showed you how to do this in the last section we basically get the existing array and filter it so here we pass a function we get a bug we want to return all bugs except the bug with the given ID we can pick that from action that payload.id simple as that now what if the type of our action is neither of this we should return the current state this is very important because if you make a mistake if we dispatch an action that doesn't exist we don't want our system to blow up we want to return the current state okay we're almost done the only part that is missing is the initial state so when we start our application the store is initially undefined Redux is going to call our reducer and pass undefined as the value of the state in that case we want to return the initial State we don't want to return undefined or null now what is the initial State here that is an empty array so we can set that using a default argument over here so when we start our application Redux is going to call our reducer and pass undefined as the value of the state in that case we're going to reset the state to an empty array okay now in this example I'm using an if and else to implement this logic we could also use a switch and case statement Redux doesn't care it's entirely up to you some people don't like switch on case if you prefer even else go for it but let me show you how to implement this logic using a switch on case so let's switch on action the type here we're going to have two cases one for bug added and another for bug removed now for each case I'm going to copy the code from here so here's our return statement cut I'm going to add it here and finally for bug removed we have another return statement very easy we also need a default case if the action type is none of these values in that case we want to return the current state so here's our final implementation now one thing I need to emphasize here is that this reducer is a pure function we talked about pure functions in the last section A pure function is a function that if we call it multiple times and give it the same argument it always returns the same result and is free of side effects so in a pure function we are not going to touch Dom elements we're not going to work with any Global State we're not going to make API calls because all these operations can change the state of our system as a whole in that case if we call this pure function multiple times we may not get the same result so pure function should be a small function in an isolated world all it needs should be passed as arguments these are the only dependencies of a pure function so this reducer this pure function takes these two arguments and Returns the new state that's all it does now this properties make it really easy to test this reducer we don't have to set some Global State before calling this function for testing so in Redux reducers have to be pure now you might be wondering how we're going to make API calls we'll talk about that later in the course for now don't worry about that foreign now that we have a reducer we are ready to create our store based on this reducer so in the source folder let's add a new file store.js now here first we should import the create store function from Redux next we call it now here we should pass our reducer so that means we should go to our reducer file and Export this function I would prefer to export it as a default object so we can easily import it in other modules so save the changes now we can import reducer from the current folder reduce our module now if we didn't do a default export we would have to wrap this in braces with the default export we don't have to do that so this is the only object that is exported from this module okay so we pass our reducer as an argument and note that I'm not calling it I'm just passing a function reference so create store is another example of a higher order function because it takes a function as an argument right now this returns a store object so finally we need to export it so we can bring it in our main application we'll do that next so we created the store now let's use it so in index.js first we should import the store from the store module in the current folder note that I'm not wrapping this in braces because I exported the store as a default object okay so here's our store now before going any further let's just log this on the console and see what it really looks like so save now there you go so a store is an object with these properties we have a method for dispatching actions we have a method for subscribing to the store so when you subscribe to the store we get notified every time the state of the store changes this is used by the UI layer you're going to see that very soon we also have a method for getting the current state of the store we also have replace reducer and symbol of observable these are Advanced topics we'll talk about them in the future now what is interesting here is that we do not have a method for setting the state of the store we only have get State not set State this is a fundamental principle in Redux so to change the state of the store we have to dispatch on action with this architecture we're essentially sending every action through the same entry point that is the beauty of Redux so back to our code let's call get State and look at the current state of the store so save so initially we have an empty array because we haven't added any bugs yet so let's dispatch an action so before console.log we're going to call store.dispatch and pass an action this action should have two properties right one is type which was set to bug added the other is payload which is an object with a property called description and we can set this to bug one so in a real application when the user clicks on the add button we're going to dispatch an action now save the changes there you go so in this array we have a bug object with ID set to one here's a description and it's not resolved now let's dispatch an action for removing this bug so right after we got a dispatch another action the type of this action is going to be bug removed and in the payload we just want to pass the ID of this action we don't need anything else so save the changes now our store is back to initial state all right now let's see how we can subscribe to the store so before dispatching an action I'm going to call the Subscribe method here we should pass a function this function gets called every time the state of the store gets changed so here we can log store change and as the second argument we can get the current state of the store so store that get state this is basically something we do in the UI layer so whenever the state of the store changes we want to refresh the UI if you're building an application with vanilla JavaScript or jQuery this is where we're going to work with our Dom elements we're going to refresh the view if you're building an application with react we're going to re-render now we'll talk about that in the future for now what you need to understand is that UI components should subscribe to the store so they get notified when the state of the store changes Okay so let's save the changes back in the browser so you can see our store changed twice this is the first time so we got a new bug and then we removed that bug now this subscribe method returns a function for unsubscribing from the store so let's store that over here unsubscribe this is important because it is possible that the user navigates away from the current page and in the new page we're not going to have that UI component so we don't want to have a subscription to the store because this subscriptions can create memory leaks so if the current UI component is not going to be visible we should unsubscribe from the store let me simulate this so let's say we added a bug now I'm going to call unsubscribe so the second time we are dispatching an action we are not going to get notified save the changes and take a look we only have one message that indicates that the store is changed the second time the store got changed we did not get notified because we had unsubscribed before you have seen all the building blocks of Redux actions reducers and the store let me walk you through the Redux workflow one more time so when we dispatch an action our store is going to call our reducer it's going to give it the current state and the action that we dispatched based on the type of the action we're going to get the new state so this dispatch method if you look at its source code it actually looks like this it calls the reducer gives it the current state and the action that we dispatched and then it will get the new state which is going to store here so this is the internal state of the store okay then it's going to notify the subscribers now in the next section I'm going to show you how to build Redux from scratch so you're going to code all of this but before we get there I need to emphasize that Redux is actually a very small and simple Library it has a small API it has a small footprint earlier you saw that the store object has only a few methods that you have to learn about get State dispatch and subscribe so there are very few moving Parts in Redux however when building real world applications with Redux we often introduce additional building blocks that make our code more maintainable for example one problem we have in this implementation is that we have hard-coded this string in two places one is here where we are dispatching an action the other is in a reducer where we're handling this action what if tomorrow we decide to rename this from bug added to bug creator then there are multiple places in our application that we have to update and if we don't do so we're going to create a bug so let me show you how to fix this problem we're going to add a new file called action types we're going to store that string in a single place and use it in multiple places so here we're going to export a constant called Bug added and set it to that string that magic string similarly we can create another constant called Bug removed this is the only place where we're using the string literal if tomorrow we want to change it this is the only place we have to update now we go to our reducer and replace the string with the constant that we just exported so on the top we're going to import we can use a named import so we can import bug added and Bug removed from the action types module that's one way the other way is if you're dealing with multiple action types we don't want to pollute this import statement so we can import everything as actions now this actions is going to be an object with properties like bug added and Bug remove let me show you so we're going to replace bug added with actions dot look we have these two properties Bugatti similarly we're going to replace bug removed with actions that bug remove well actually I should have used bug removed so let's rename this to bug removed okay good now finally in our index.js when dispatching an action we're going to use that constant one more time so let's import everything as actions from action types and then we're going to set the type to actions Dot Bugatti as simple as that the other problem we have in this implementation is how we dispatch an action as you can see dispatching an action is not easy we have to type the entire structure of this object now what if there are multiple places where we want to dispatch the same action then we have to repeat all this structure in multiple places to improve this we can create a function that would create this action object for us we call that an action Creator so in our project in the source folder let's add a new file we can call it actions or action creators I prefer actions but that's entirely up to you so here you want to create a function called Bug added which takes a description and then returns this object structure over here so let's cut that and then paste it here pretty simple right now we can export this and import it in our main module so in this case we don't need this import statement anymore because we need action types only when creating an action so I cut that line and paste it here okay this is where we're using our constant now in the index module I'm going to import bug added from the actions module so here we have a named export because bug added is not a default export okay now when dispatching an action we simply call this function bug added and give it the description this makes our code a lot cleaner and if you want to dispatch the same action from multiple places we simply have to call this function we don't have to worry about the structure of this action object if tomorrow we want to change the structure of this action there is a single place that we have to update okay so this is why we use action creators now I personally prefer to create my action creators using an arrow function because they have a more concise syntax let me show you so let me comment this out now you're going to export a constant called Bug added and set it to an error function this function should take description as a parameter and return an object so here we cannot use curly braces because these braces indicate a block of code but here you want to return an object so we should wrap this in parenthesis now this is the action object that we want to return so it should have these two properties type and payload I copy these paste them here and then remove the comet so this is another way to create an action Creator now what syntax you use is internally up to you here's an exercise for you I want you to implement resolving a bug so we should be able to create a bug and then Mark it as resolved spend five to ten minutes on this exercise and then come back see my solution to implement a new feature with Redux you should always think about your actions first and then your reducer so we want to define a new action or a new capability or a new event that can happen in our application that is resolving a bug so first we go to our action types module and Define a new constant called Bug resolved once again I'm using the past tense here to represent an event that just happened so we set it to bug result next we should create an action creator so in the actions module we export a new constant called Bug resolved and set it to a function now what pieces of information do we need for resolving a bug at a minimum we need to know the idea of the bug so it is going to be a parameter until you're going to return an object so we wrap that object in parenthesis now the type of this object is going to be actions.bug resolved note that the benefit of importing the actions using the syntax is that every time we Define a new action every time we Define a new constant we can simply use it in this module in contrast if we used named Imports let's say bug added from action types every time we Define a new action type we have to come back and add that new action type here so this is a simple tip we import everything as one object now we set the type and then the payload here we can simply add the idea of this action now in modern JavaScript if the name of a property and the value are the same we can use a shorthand syntax so we get rid of it and by the way I noticed that in the last video I made a mistake a hard-coded bug one here but we should set the description property to the description argument so we save the description or use the shorthand syntax all right we're done with our action now we should change our reducer so it can handle our new action so let's go to reducer.js here we want to add a new case actions dot bug resolved see that's another benefit of importing all the actions as a single object I didn't have to go on top of the file and import our new action Okay so when a bug is resolved we want to update an existing bug object I talked about this pattern in the last section so basically you want to use state.map here we pass a function it takes a bug now if the idea of this book does not equal action that payload.id if this condition is true we want to return this bug as is otherwise we want to take a copy of this bug and modify it this is updating in an immutable way so here we want to return a new object first we want to copy all the properties of the bug and then we want to set the result property to True okay let me put this on a new line so you can see clarity so using the map method we're mapping this array to a new array if the idea of the book is not equal to the idea of the bug that we have resolved we're going to return that bug otherwise you're going to return a new bug object with all the properties of the existing bug but with the updated resolved property as you can see writing code like this is a little bit confusing and complex that is why we should use libraries like immutable JS or immer this is one of the main reasons that a lot of people find Redux confusing but don't worry later in the course I'm going to show you the modern way of writing Redux code that is very clean and concise for now I want to use the traditional way because that's what you say in most projects so a reducer is now capable of handling this new action or this new event with that we can go to our index module and after creating a bug we want to resolve it so store the dispatch we should import our new action Creator bug resolved then we call it over here bug resolved give it the ID and we're done save the changes so take a look in this array we have one bug that is resolved beautiful hey mosh here thank you for watching my Redux tutorial as I told you before this tutorial is the first hour of my complete Redux course that is 6 hours long and covers a lot more so if you want to learn more I highly encourage you to enroll in my complete redox course you will also receive a certificate of completion that you can add to your resume if you're interested up with the link down below thank you for watching and we hope to see you again please support me by liking this video and sharing it with others and be sure to subscribe for more videos like this [Music]