Instructor: 00:00 We've got a basic React and Redux application running here. We're able to add to-dos by typing into the input and pressing the add to-do button. To remove a to-do, we simply need to just click on one.
00:10 We have this to-do list component that only keeps track of the input state from the input box. Our handler functions for clicking on the button and clicking on the to-do to remove one calls Redux action creators.
00:27 Then we use our Redux reducers to help us keep track of our to-dos. As you can see, we're just mapping over these and creating LIs. This to-do list is all that's being rendered from our main app component.
00:42 I've placed all of our Redux concepts into this one file called Redux. Here at the bottom, we're exporting out our store and passing it through to our main app component.
00:56 The first thing we do in our file is create our two action creators -- the adding of a to-do and the removing of a to-do. Next, we have our initial state and our reducer methods. We're calling that currentList. Then we pass it on through to our store.
01:13 To get started with our middleware, let's do const loggerMiddleware = store => next => action. console.log action to be dispatched with our action. Then next(action). Then console.log('state after action:', store.getState()). Perfect.
01:35 As you can see, our Redux middleware is just a series of curried functions. With each function, we get valuable arguments we can use inside of our closure. Because we have access to our store, we can use the getState method.
01:49 The next curried function will be given the next middleware's dispatch method, and is expected to return another function of an action calling next on that action.
02:01 We're console.logging the current action. Then we dispatch that action with the next function here. Then we console.log whatever the store's state is after our action is dispatched.
02:12 In order for our middleware to run, we need to bring in applyMiddleware from Redux and pass it through on the createStore function, passing through our loggerMiddleware. With our middleware wired up with our store, we can add a to-do like "Buy milk."
02:25 When we press the add to-do button, we're going to get two console.logs, our action to be dispatched, which is our add to-do with our object of text to "Buy milk." Inside of our store state, our currentList to-do array has one item in it, and that is our "Buy milk" to-do.
02:42 We can click on it and remove the to-do, which is going to fire the removeTodo action. Now our state has nothing in the to-dos array. As you can see, middlewares can help us remove or add functionality to our application with each dispatched action.
02:58 Now let's create a second, more useful middleware. Let's write const localStorageMiddleware = store => next => action.
03:08 Then we'll next our action. const todosJson = JSON.stringify. store.getState.currentList.todos. Then console.log this.todosJson.
03:18 Then we'll window.localStorage.setItem(todos) our todosJson. For each action that's dispatched, whether it be adding or removing a to-do, we're going to keep a copy of our current state to-dos in local storage. This way, our state is consistent even when we refresh our page.
03:41 Let's update our initial state reducer to check the window's local storage to see if it has any to-dos in there. We'll JSON.parse our localStorage.getItem(todos). If not, then we're just going to return an empty array.
03:58 Let's make sure that we pass through our second middleware on through to the applyMiddleware. If we add a to-do like "Buy milk" again, you can see we have three console.logs, with the second one being our JSON stringify to-dos.
04:12 If we refresh the page, our to-dos stays consistent. That's because our reducer is checking our local storage. We can see that in our application tab here.
04:25 We can remove or clear our local storage simply by deleting the to-do. Now our reducer is just returning that empty array. With our local storage middleware commented out, our to-dos disappear when we refresh our page.