Vue and React are two of the most popular front-end JavaScript frameworks used for building user interfaces. While both frameworks have their own strengths and weaknesses, they both provide powerful tools for managing the state of an application. In this tutorial, we will explore how to share state and handle complex state updates in Vue and React.
Sharing State in Vue and React:
In both Vue and React, state management is essential for building dynamic and interactive applications. State refers to the data that is used to render components, handle user interactions, and control the behavior of the application. In Vue, state is typically managed using a central store called Vuex, while in React, state is managed using either the useState hook or a state management library like Redux.
To share state between components in Vue, you can use Vuex, which is a centralized store for managing application state. Vuex provides a way to define reactive state properties and makes it easy to share state between different components.
In React, you can use the useState hook to manage component-level state or create a global state using a state management library like Redux. With Redux, you can define a central store that holds the entire state of the application and use actions and reducers to update and retrieve state.
Complex State Updates in Vue and React:
When working with complex state updates in Vue, you can use Vuex mutations and actions to update the state in a consistent and predictable way. Mutations are synchronous functions that directly update the state, while actions are asynchronous functions that can perform side effects before committing mutations.
In React, you can use the useState hook to update component state with the useState function. To handle complex state updates, you can use the useReducer hook, which allows you to define a reducer function that updates state based on a given action.
To illustrate how to handle complex state updates in both frameworks, let’s consider an example where we have a shopping cart component that needs to update the quantity and price of items in the cart. In Vue, we can define mutations and actions in the Vuex store to update the cart state, while in React, we can use the useReducer hook to define a reducer function that updates the cart state based on actions.
Vue Example:
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
cart: []
},
mutations: {
updateCart(state, payload) {
const item = state.cart.find(item => item.id === payload.id);
item.quantity += payload.quantity;
item.price += payload.price;
}
},
actions: {
updateCart({ commit }, payload) {
commit('updateCart', payload);
}
}
});
React Example:
// ShoppingCart.js
import React, { useReducer } from 'react';
const initialState = {
cart: []
};
const reducer = (state, action) => {
switch (action.type) {
case 'UPDATE_CART':
const item = state.cart.find(item => item.id === action.payload.id);
item.quantity += action.payload.quantity;
item.price += action.payload.price;
return { ...state, cart: [...state.cart] };
default:
return state;
}
};
const ShoppingCart = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const updateCart = payload => {
dispatch({ type: 'UPDATE_CART', payload });
};
return (
<div>
<button onClick={() => updateCart({ id: 1, quantity: 1, price: 10 })}>
Add Item
</button>
</div>
);
};
export default ShoppingCart;
In both examples, we define a mutation or reducer function that updates the cart state based on the payload provided. We then use the mutation or dispatch function to update the cart state when a user action is performed.
In conclusion, both Vue and React provide powerful tools for sharing state and handling complex state updates. By using Vuex in Vue or the useState and useReducer hooks in React, you can effectively manage state in your application and build dynamic and interactive user interfaces. Experiment with both frameworks to find the right tool for your project’s needs and requirements.
amazing video. thx for the insight
Can't react user just import vue features ? I think it's possible
Great insights about immutability and reactivity! Love this fair comparison.
Would this change if we used a Map instead of an Array? I feel like some of these complex updates come from using an array and could be simplified with a Map (this is a question, not a statement haha).
i freaking love CJ! GOAT
for simple stores, using shared composables is actually very intuitive and reactive by default. I could use it over Pinia for almost anything on small/simple apps
vue is GOAT
I've been using both since Vue 1.0 and it (Nuxt) is always my choice for projects where I get to decide what to use. I only use React when I am forced to do so because of legacy code / project.
I think most Devs would choose Vue over React if they were making a fresh start.
The Vue docs have also always been the gold standard.
How is that going to work with SSR? Won't you be sharing the same global state across all of your users?
This is the best Vue advertisement you can get. React is basically workaround after workaround.
For state management in React, I've been using Legend-State, it's the closest you can get to DX of other frameworks like Vue and Svelte while not sacrificing performance (fine grained reactivity).
There's an interesting nuance with use-context-selector – the component's render function will still be called, but updates in deps (for example, useEffect calls) won't occur 🙃
In any case, in my opinion, the lack of separation between initialization and render phases for user code is inconvenient. 10 points to Vue.js
I am more of a Vue user and like it a lot. Thank you for your great comparisons, it's very helpful and easy to follow.
I don't know if the Vue Dev Tools have this feature either. Your mixin solution leaves me a bit irritated because what is this line of js/ts and its weird syntax? "void this.$el.offsetWidth"
Love inject/provide, but it's true, most of the times you reach for either a composable or pinia.
But my FAVORITE way of using inject/provide is to connect "generic" components.
It allows you to write something that can be used like:
<ButtonGroup>
<OptionButton />
<OptionButton />
</ButtonGroup>
Where each `OptionButton` is aware of their sibling because of an context provided by `ButtonGroup`.
I should probably write an blog post about that
It is such a pleasure to see Vue getting some love ♥
react was a mistake
So I am working with react for like 2 years. The fact, that I have managed to learn Vue 3 in maybe 4-5 weeks and them migrate production App that we use at work from Vue3 options to Vue3 composition script setup API(that's a mouthful) and add Router and Pinia (hands down, the best global state managment) within weeks is unreal. I wish we would create more Vue apps.
I am switching sides now. I love Vue 😃
Amazing content! Personally, since Vue 3 and the composition API, I don’t even use Pinia anymore. I simply use a reactive object returned as a composable. Then again, my use cases are pretty simple.
Is there any performance improvement from using inject/provide over a pinia store?