4.15 Writing Store Mixins
Several of our components have identical methods for dealing with stores. We're going to create a mixin to factor out that duplicated code.
1.Getting Started2 lessons, 03:51
2.Project Setup3 lessons, 20:58
3.Server-Side Code6 lessons, 53:00
4.The Client Side16 lessons, 2:43:53
5.Conclusion1 lesson, 00:29
4.15 Writing Store Mixins
One of the things you may have noticed as we've been producing these different components is that several of them have very similar functions. In fact all of our components that need to update in some way when the store updates have these did component mount and component will un-mount functions. Now of course these are built in react functions that will be called at the right time, and we're using them to add change listeners and remove change listeners. However, it's unfortunate that we have to have this code duplicated across these different classes. For the record, we have this in the follow button, we have it in our home class, we have it in our user list class, and we have it in our user profile class. And in user profile, we're actually listening for both the user store and the chirp store. So what you might be wondering is, is there someway we could pull these methods into a single place and not have them duplicated like this? And the truth is we can do this in React with a mix in. A mix in is basically an object with a certain number of methods that we want to add to a react class. So what we're going to do is have a store mix in. And the way you would use this store mix in goes like this. So we're here in our follow button component. And what we'll do is we'll add a mix ins property to our class, and this is going to be an array. And then what we pass to this array is the object whose methods we want to mix into this class. So if we make our mix in as a property of our store object, as we're going to do, we might do something like UserStore.mixin, and this will be the object that we want to mix in. So to do this, we would have to add a mix in property to our UserStore. And instead of adding it directly to the UserStore, let's put it on our store.js file. This is of course our store constructor and we can do this down here in the store object that we created inside our extend method here. In here we will add a mix in property to this object and inside mix in we want to include those two methods we have in every case so we are going to have componentDidMount and componentWillUnmount and I am going to copy them from follow button and I am just going to paste them right in here and let me format this nicely. And that is actually most of the work that we would need to do. Of course, we don't have a reference to UserStore from within this function. However, whether we're using UserStore or ChirpStore, from within this mixin, we can reference that by referencing our store variable right here within the extend function. So I can just say store.addChangeListener, and for this one, we will add store.removeChangeListener. Now, you might be wondering, what about the onChange function? Well, there are a few hacky ways that we could include our onChange function within our Mixen here. The main reason it has to be a little bit hacky is because if we had the onChange method in here that is not a method name that React knows something about. Right? It knows about componentDidMount and componentWillUnnmount. And so if we had a single react class, as we're going to, user your profile here, a single react class that needs to mix in the user store and the chirp store. Well then react is smart enough to know that if our mixing includes methods like componentDidMount and componentWillUnmount. It will call those versions for every mix in, right? So we could even include a componentDidMount within our actual class and it'll call that and it'll call the other ones that it Inherits from, if you will. However, if we have a custom method such as onChange, we can't be overloading that method name with multiple methods. So, within user profile here, the UserStore mixin would try to add an onChange method and then, the ChirpStore would also try to add an onChange method. And React would complain about this, saying that multiple mix ins are using the same function name. Unfortunately, there's no easy way to give our. Now unfortunately there's no real easy way in React at this point to give these methods a unique name. The best idea that I could come up with would be to use a symbol as this function name instead of an actual name like this. But even apart from the browsers that that wouldn't work in, right now React doesn't support mix ins with symbols and names. So we're are just going to have to leave the onChange functions within their classes. However just this by itself will make our code a little bit cleaner. So we can see this in action if we go to the follow button here, we already have our user store mix in but let me remove the componentDidMount and Unmount functions. Gulp is watching and your sever is running so I can go ahead and log in. And if we go over to our users list over here and I can go ahead and follow MollyDoe. And you can see that the button has still changed to be unfollow. So that's behavior that happens because of those change listeners which means that even though our follow button is now using our mix in, it still works successfully. So let's go ahead and use this mixin in our other classes. In home here, I can remove componentDidMount and componentWillUnmount. And we will have our mixins array. And this will just include ChirpStore.mixin. In the user list we're using the UserStore of course. So our mixins array will be UserStore.mixins and I can remove our two component functions. Finally, in user profile, as we already mentioned, we want two mixins. So, I'll say userStore.mixin and I can also say ChirpStore.mixin. And we'll delete those two functions. And why don't we check out user profile, just to make sure that it's working correctly? So, if I come back and refresh our page and then I click on John Smith, you can see that we are seeing his profile just fine. If I go back to the Timeline and look at my own profile, you can see we are seeing CHIRPs as well, so it looks like even our class mixing in, multiple mixings is working just fine. So that is using mixins with react. It's a very handy way to abstract some of our functionality into single place. And now that I'm thinking about it, it would be really nice if we could move onChange. So, let me show you the hacky way that I had in mind. And you can choose whether you want to use it or not. Basically, the easiest way to give our onChange functions different names each time, is to append an incrementing number onto the end of those function names. Let me create a number up here. This will just be num and we'll set it equal to 1 for starters. Then, the other thing is that mixin here needs to become a function that we can call that returns an object. So, I'll say, mixin becomes a function. And inside of it we have this object. Now the first thing we want to do inside mixin is get our number. So we'll say var n = num++ to increment that number after we get it. And then we can say here the function names need to be onChange + whatever that number is. And then for componentwillUnmount we'll do the same thing. And of course this will be the same number, because of course we won't remove the listener that we just added. So then, of course, we actually need to create this onChange [INAUDIBLE] function, so we can say object['onChange' and we'll add that number in there, and this will equal our function. And for this function's content, I'll just copy this single line that we have in onChange And our follow button here, we're calling this.setState and we're passing it the result of this.getInitialState. All right, and so then right at the bottom of our mixin function, we'll just return that object. As you can see, it's a little bit hacky. However it should work. So now what I can do is within the follow button here, I can remove onChange. And the other thing I have to do is instead of just getting UserStore.mixin, I actually have to call it because it's a function. So let's go ahead and change that in all the places that we have our mixin. And this will work specifically for user profile because it will get two different on change functions with two different names. If I come back to the browser and I refresh user zero you can see that everything is still showing up. So there you go, you can choose whether or not to use the, so there you go. You can choose whether or not to use our hackier version but whichever you choose that is mix ins with React.