What we are dealing with here in this particular example. First of all, we deal with synchronous changes in the state, that's why I said that probably we won't even need an action. We don't have any asynchronous behavior here. It's non-persistent, so whenever I update the page count will be zero again. We don't need to store this anywhere else outside of the Vuex state. It has one source of changes, so this is like our magical single source of truth, that only is responsible for changes of count in our application. Count can be changed anywhere else. It's stored only in Vuex and changed only in Vuex.
And yes, it does not create a lot of boilerplate. This point can be a bit debatable, because three different properties for changing one count... Still, it's a reasonable amount of boilerplate for this change, considering the fact that count will be shared all across the application. But all of this is not as nice when we start dealing with server data. So let's add some server data to the equation in our Vuex state. Here, at a first look, it looks like the same count. We have a property characters, we have an imitation that changes characters, and we have some asynchronous action that fetches data from our character's endpoint. And after this, we commit a mutation, so everything is fine.
But with this, your application is not sufficient because fetching characters is an asynchronous operation, which means that there will be a moment in your app when there are no characters and you are idle. You are waiting for your API to return your data. And of course, you need to add a loading state, because we need to show this nice loading spinner or skeleton or whatever you're showing in your application. And also, we are fetching data from the API. And what if the response is not there? What if your quest wasn't successful? We need to handle errors, which is a super good practice for any asynchronous call. And that's why we need to add one more flag—error—to our application. And with this, our simple structure of one-action-one-mutation becomes not as simple, because you need to update loading, you need to update error, and here is quite a common convention Gateweb uses as well to handle asynchronous behavior with free quests. So here we have like three finite states—a loading state, a success state, and an error state. And here we are setting loading to true, error to false, so we are in the loading state now. Then we receive our characters, everything is fine, loading is false, error is null, characters are here, and we render the array of characters, and of course there can be some error state. So in this particular case, we set loading to false, we say that error is something that server returns to us, characters select three mutations. Yes, you can simplify it if you have the only one, but if you want some kind of standard, usually companies come with something like this. And now our action is not as simple as well, because when we start an action, we go into this loading limbo state, requesting a character, and then we have characters, we commit the success mutation, storing the characters to the state, and then if there is an error, we also commit an error mutation, and if you imagine all of this boilerplate, it's quite big already. So yeah, it's huge for one single request, and if we have multiple requests, probably we have different loading states, or should it be the same loading state? Every single time we do this, you need to rethink it and to understand if we want to share loading states between different requests in our application, and this still doesn't answer a bunch of questions.
Comments