React VS Vue | What about them?
Atif Aiman
Posted on August 19, 2021
There are a lot of Javascript frontend framework in market right now, in which their hype to their own. The famous 3 - Angular, React and Vue (Svelte is still in the race as well), and also honorable mention for MeteorJS, Ionic. Of course there are higher frontend framework as well such as NestJS, NextJS and NuxtJS, but let's leave them for another discussion, shall we?
The purpose of this writing is not comparing both great framework for modern web app, but to highlight both features that gives the great developer experience, and where they can interchange the knowledge between both, so you won't have to start from scratch.
Disclaimer: I have professional experience in React for more than two years (and still counting upon me writing this article), and I just involved in Vue in my new project, so the comparison might not be fair towards Vue, so I hope I can do the best I can for Vue as well.
Another disclaimer: This is not a proper documentation for both frameworks, so if you look on how to use the framework, I recommend you to go to the documentation for the respective framework.
The Similarity
Both are javascript framework. I know right 😜?
Just kidding! Let us see the similarity offered by both before highlighting features those are unique to the respective frameworks.
Virtual DOM
Document Object Model (DOM) is an object that defines the document structure. To put it the easy way, the way you arrange all HTML elements. To optimize the DOM rendering when there is a change, both utilizes virtual DOM, where the DOM is structured right before the page with changes displayed to the user, so user won't have to experience a glitch.
Event changes
Both relies on event changes, where state plays an important role in triggering events such as mounts, renders, and updates (known as lifecycles). Differs with traditional JQuery approach, where you have to trigger the event on your own, React and Vue helps developer to encapsulate everything into an event, so the rerender can be triggered when there is state changes.
Component-based
To be able to produce components are what makes the framework the choice of developers, since it can save a lot of work, holding to the Don't Repeat Yourself (DRY) principle.
React
JSX
When you mention React, JSX will always come into play. Though you feel like you are writing HTML, you are actually using JSX, where Javascript will parse it in object later on and React will run the function to convert in into something like document.getElementByElement
. That is why, inside JSX, you have to use className
instead of class
since the word class
is reserved in Javascript.
const Component = () => {
return (
<div className="wrapper"/>
);
}
Declaratives
Since we composite everything under single function for a single component, it is easy to use the declared variable.
const Component = () => {
const name = "John";
return (
<p>{name}</p>
);
To trigger all javascript inside JSX, you only need to open curly braces, and you can do anything.
const Component = () => {
const names = ["John", "Adam", "Mark"];
const [age, setAge] = useState(12);
const increaseAge = () => setAge(age++);
return (
<div>
{ names.map(name => (<p>{name}</p>) }
<button onClick={increaseAge}>Increase Age</button>
</div>
);
};
Hooks
Don't get me wrong. Vue also has its own hook. However, React really has its strong suit with their hook implementation (given that you need to use functional pattern to use it). Before this, React uses Higher Order Component (HOC), which can also be implemented for both class component and functional component. To make it more verbose, React introduces hooks, which later introduce more verbose pattern and developer is able to split their code based on functionality, and not lifecycle. The most basic hook, useState
and useEffect
are the most used hooks in React ecosystem.
const Component = () => {
const [state, setState] = useState();
useEffect(() => {
console.log("Hello console!");
});
};
States and props
What I love about React is how you can actually optimize the state and props. From useState
, you can optimize by memoize it using useMemo
, then if you need to elevate and group bunch of states, you can use useReducer
. Note that, you also need to know the cost of using the hooks as well.
To pass the props, you can simply pass it along with the function of the component as below:
const Component = (props) => {
// The rest of the component
<p>{props.name}</p>
};
When you import the component, you can pass anything that you need to the component this way:
<Component name="John" />
Let say, you don't have a lot of changes happened to a certain component, we can also use pure component, so the render is predictable for the renders, and you don't have to put useState
inside it.
React Lifecycle
React has a standard component lifecycle - mount, update, unmount. In class component, there are methods that is used, like componentDidUpdate
, componentWillUnmount
. In functional components, its all packed inside useEffect
, where you can set which changes will it subscribe to, and split code better.
const Component = () => {
useEffect(() => {
// Functions here are equivalent to
// `componentDidMount`, `shouldComponentUpdate`
// and `componentDidUpdate`
return () => {
// Functions here are equivalent to
// `componentWillUnmount`
};
}, [changesDeps]); // Changes can be state, props
};
Note that useEffect can be used repeatedly, oppose to class lifecycle method which can only be used once in a single class.
Vue
Before going into details about Vue, I will only use Vue 3 approach, mostly on Composition API. For React developers, I personally use Vue Composition API which are really similar to React. I might touch a little bit about the usual pattern, just to compare how simple Vue has been in term of verbosity and optimization.
Templates
Differs with React, Vue uses the usual HTML pattern, and not JSX. That is why, Vue recommends usage of templates (though you can also use render function and JSX if there is the need). You can use the usual pattern, including the usual element class.
<template>
<div class="wrapper"/>
</template>
Declarative
Vue has its own style of declare a variable. In traditional way, you can pass variable as data
when you export the component, along with the templates.
<template>
<div>
<p>{{ name }}</p>
</div>
</template>
<script>
import { defineComponent } from 'vue';
const Component = defineComponent({
data() {
return {
name: "John",
};
},
});
</script>
However, starting Vue 3, where Composition API has been introduced, it provides developer a new way of writing the component, where React developer such as me, feel close to home, and helps me to adopt Vue as fast as I can.
Note that Composition API in Vue 3 didn't totally replace the old pattern in Vue 2, it's just providing a more verbose way of writing your component.
<template>
<div>
<p>{{ name }}</p>
</div>
</template>
<script setup>
const name = "John";
</script>
Simpler, right?
So, how about render that involve conditions and loops? Vue introduce binding, where you bind a variable to the content inside the template.
<template>
<div :class="wrapperClass" v-if="counter < 3">
<p>{{ name }}</p>
<button @click="increaseCounter">Increase</button>
</div>
</template>
<script setup>
import { ref } from "vue";
const name = "John";
const counter = ref(0);
const wrapperClass = "wrapper";
const increaseCounter = () => counter++;
</script>
States and props
Noticed that before this, we have a thing called data
? Yeah, it serves the same purpose as React's state
, where it will handle reactivity. This is to make sure the state is immutable. But in the following example, I'll just show the script setup
equivalent.
<template>
<div>
<p>{{ counter }}</p>
<p>{{ user.name }}</p>
</div>
</template>
<script setup>
import { ref, reactive } from "vue";
const counter = ref(0);
const user = reactive({
name: "John",
});
</script>
So, how about props? Okay, let me show you the old and the new way.
<template>
<div>
<p>{{ counter }}</p>
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
props: {
counter: Number,
},
});
</script>
<template>
<div>
<p>{{ props.counter }}</p>
</div>
</template>
<script setup>
import { defineProps } from "vue";
const props = defineProps({
counter: Number,
});
</script>
So, when you you import your component elsewhere, it behaves the same way as React pass the props.
<template>
<Countdown counter="3" />
</template>
<script setup>
import Countdown from "../sources/";
</script>
Vue Lifecycles
The flow of lifecycles between React and Vue are generally same, with Vue introducing some addition to the process. (I haven't use lifecycle extensively yet, so I will update it if I find new information).
So, the old way (Option API)
<script>
export default defineComponent({
mounted() {
// Execute function after mounted
},
});
</script>
The script setup
way (Composition API),
<script setup>
onMounted(() => {
// Execute function after mounted
});
</script>
There, you can see the usage of hooks inside Vue!
Conclusion
React and Vue both offers their own way of managing states and props, the lifecycles, and their own way of binding and executing function to the HTML. Of course the next question should be "which one is better?", nevertheless both have evolved tremendously and will improve in future. So again, my aim to highlight the feature from both sides, so we can mutually recognize each pattern. Later, you can jump right to the other side, without worrying about relearning again.
Which one is easier for me? I will still say React is easy-win for me, but that doesn't give a fair comparison to Vue, given that I am still new to Vue.
If there's a missing part, that you believe is the key to each framework, comment down below 👇!
Posted on August 19, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.