Redux vs. Vuex:
This week’s post is going to be a bit different from the usual posts about weekly goings on at Codesmith. The change is because this week is all about ideation for a production project which I and two cohort-mates are working on. We’re all really excited about a framework that got a lot of attention this past year, Vue. I’ve read a lot about the differences between Vue and other frameworks, but I was also really curious about how different state management libraries work with Vue. I decided it might be nice to get a little bit into the differences between Redux and Vuex, the official state management library for Vue, and share my findings.
Here we go:
Redux is a framework agnostic state management library. If you’re thinking about trying out Vue, or already using Vue with Redux, Vuex is probably a better state management library for maintaining performance, Here are some things to know about the two, so you can compare:
Redux relies on actions: objects with a ‘type’ property and the minimum number of other properties and values that are necessary to explain the action. The only way to manipulate your state is to use the store.Dispatch() method which takes in a type (your action object) and a payload(which sends data from your application to your store). If the action isn’t recognized and no change is dispatched, the state is defaulted to the old state.
Reducers are pure functions (with pure functions you can guarantee that the same input will always result in the same output and do not mutate the input or create any side effects) that are used to implement how the next state is calculated from the current state and the action.
Each reducer manages its own part of the global state. State logic can be managed by breaking down your reducers to correspond to smaller sub-pieces of a state. These reducers can then be combined to one root reducer to manage all of your applications state. The redux store saves the complete state tree returned by the root reducer.
The store is the single source of truth and holds the whole state tree. In truth, it is just an object. To change the state, you must dispatch an action to it. In Redux, there is only one store, and one root reducing function, similar to having a root component in React. You never add a store, you only split the root reducer into smaller reducers that work on different parts of your state tree. You can add a change listener called subscribe to check anytime an action is ‘dispatched’ and your state tree may have changed.
FYI, you can bind Redux and Vue.js, just keep in mind that according to some, it is not necessarily the best fit for Vue.js. This is because Redux replaces the state object on every update. Though Redux is framework agnostic, it was created with React in mind. React is different from Vue in the way it processes updates: React renders a virtual DOM then calculates the most optimal DOM operations to make the currently rendered DOM match the new Virtual Dom. But it has no way of knowing whether a particular component needs to re-render or not based on the new data. Vue instances keep track of which bits of data they depend on to render. These instances automatically register what needs to re-render when the data changes.
Similar to Redux, Vuex is also inspired by Flux. However, unlike Redux, Vuex mutates the state rather than making the state immutable and replacing it entirely like with Redux’s ‘reducer’ functions.
This allows Vue.js to automatically know which directives need to be re-rendered when the state changes. Instead of breaking down state logic with specialized reducers, Vuex is able to organize its state logic with stores called modules.
Rather than actions, the only way to change the state tree in Vuex is with Mutations. Mutations require a type and handler. The type is a string name that acts as the key, and the handler is a function body. The mutations can be assigned to modules with a corresponding slice of the state. For small apps, this might seem tedious, but the benefits are that (particularly for larger apps) you will have one place where you will be able to see all of the possible ways that the state can change. This makes debugging much more convenient. Also, note that these are always synchronous to ensure that the state isn’t dependent on the timing and order of unpredictable (asynchronous) events.
In Vuex, we also have actions: these are functions that dispatch (communicate changes to the store) our mutations. These can be asynchronous and receive the store instance as their first argument.
Actions do not mutate the state directly, but only commit the mutations. These can also be used to make asynchronous state changes. Keep in mind that the actions support the same payload format and object-style dispatch as mutations (i.e. your arguments for dispatch look the same as in a commit).
Like Redux, Vuex also has a store. This is the center of every Vuex application. This store holds the entire state, but it is not like a plain global object. Vuex stores are different because when components get state from the store, these components can reactively and efficiently update ‘whenever the store’s state changes. The store’s state can only be changed by committing mutations.
Overall, Vuex was really built to take advantage of what makes Vue unique. But for anyone thinking of moving over Vue, there is a caveat. For one, Vue doesn’t yet have the support, resources, and wide spread adoption of other frameworks like React. Having said that, Vue makes serious efforts to have lots of functionality right out of the box so getting started on your project is a more straightforward experience than setting up with React.