React Hooks were introduced with the React 16.8 update, and since then, they have become a necessity for single-page applications. They are a function type that allows you to hook into React state and lifecycle methods.
With the introduction of the Vue 3 update, Vue.js has challenged React with its new Composition API, which can extract pieces of reactive logic and share the code with other components.
This article will compare the Vue Composition API and React Hooks to help you understand the differences and similarities between them.
React Hooks are only featured in React functional components. These functional components execute with every rerender.
The following code example demonstrates how to use React Hooks. Initially, import the useState and useEffect Hooks from React. Next, use the useState Hook to add a local state inside the React functional component. Finally, use the changing function of useState to increment the value of the count with the help of the button onClick event. This useEffect runs on every render and will update the document title with its current value.
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = You clicked ${count} times ; }); return ( <div><p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); /** * when you click 10 times, * document title and paragraph will be displayed as "You clicked 10 times." */ } export default Example;
The following code example shows only the script part of the Vue component. On top of it, we imported watchEffect and ref to define a variable and keep track of it. Inside the setup component, the price is defined with an initial value. The console log will give the updated value every time the price changes.
<script> import { watchEffect, ref, defineComponent } from "vue"; export default defineComponent({ name: "Store", setup() { const price = ref(10); watchEffect(() => console.log(price.value)); return { price }; }, }); </script> <template> <h3>Price</h3> <input v-model="price" id="price" placeholder="edit me"> </template>
useState is famous among the React Hooks and helps us to claim reactive objects. A two-member array represents the React useState, the first being the current value and the second being the function that can change the value.
function Example() { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
You can define the reactive object inside the new setup() component in the Vue Composition API. Unlike in React, you do not need to provide a mutation function (setCount) to change the value.
<template> <p>You clicked {{count}} times</p> <button @click="count += 1"> Click me </button> </template> <script> import { ref } from "vue"; export default { name: "Hooks", setup() { let count = ref(0); return { count, }; }, }; </script>
React has defined some rules for utilizing Hooks:
Although these rules prevent issues like changing the order of Hooks execution by calling Hooks inside conditional blocks, the default behavior of setup() in Vue will prevent them, as it executes before the component is created.
Vue draws more lines to perform the same functionality possible with a single line of React code. So yes, React Hooks is a valid choice for an elementary code like this. But when the code is complex, it will be easier to use the Vue Composition API than React Hooks. So, let’s add more variables and examine what looks better.
// React const [name, setName = useState('Apple'); const [price, setPrice] = useState(20); const [quantity, setQuantity] = useState(100); // Vue setup () { return { name: ref('Apple'), price: ref(20), quantity: ref(100) } }
So, it’s a win for Vue’s Composition API.
Let’s now see how to update the value of a variable. This comparison might be your decisive point in the battle between React Hooks and the Vue Composition API.
Inside the React function component, we defined a local state called name with its initial value, Apple. Then, we introduced an input element with an onChange event to change the value.
import { useState } from 'react'; function Example() { const [name, setName] = useState('Apple'); return ( <form> <input type="text" value=name onChange={e => setName(e.target.value)} /> <h2>My favorite fruit is {name}</h2> </form> ) }
Even though React tries to use native JavaScript whenever possible, Vue has new syntaxes like v-model making the code look pretty. The following example shows how we change the value of the local state name by using an input field.
<script> import {ref} from 'vue'export default { setup(){ return { name: ref('Apple') } } } </script> <template> <form> <input type="text" v-model="name"/> <h2>My favorite fruit is {{name}} </h2> </form> </template>
The previous code example demonstrates how easily you can change a variable with Vue. The main point is that the Vue code is more precise and readable. Such well-organized code will be handy when debugging.
Examples of side effects include data fetching, setting up a subscription, and manual modification of the DOM. React attempts to handle side effects using the useEffect Hook.
The following useEffect Hook does not use any dependencies. With every render of the function, useEffect will be executed. It continuously updates the document title with the current value of the count state.
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button></div> ); }
The Composition API has two methods for dealing with side effects, watch and watchEffect. Nevertheless, they have their uses.
When multiple variables change, React’s useEffect allows the developer to keep track of these variables and activate a callback function. watchEffect is something we especially think of with Vue’s Composition API, but it does not keep track of the variable values. To achieve that, we have to use a watch().
The following example shows how to implement watchEffect. Whenever the price value changes, watchEffect will be executed and give the console log.
<script> import { watchEffect, ref, defineComponent } from "vue"; export default defineComponent({ setup() { const price = ref(100); watchEffect(() => console.log(price.value)) ); return { price }; }, }); </script>
Case 01: useEffect(() => { //Runs on every render. }); Case 02: useEffect(() => { //Runs only on the first render. }, []); Case 03: useEffect(() => { //Runs with first render OR whenever the dependency value changes. }, [prop, state]);
//The callback is called whenever `refA` changes. watch(refA, () => { console.log(refA.value); });
//The callback is called immediately, and //whenever `refA` or `refB` changes ... watchEffect(() => { console.log(refA.value); console.log(refB.value); });
Note: The main difference is that the watchEffect starts instantly while the watch() runs lazily.
The basis for everything we discussed throughout this article is JavaScript. So first, we went through the React Hooks and alternatives provided by Vue Composition API.
React does not attempt to deviate much of its code from Vanilla JavaScript. And Vue uses fewer lines of code and less time to perform the same operation that React Hooks does. We realized that the Vue code is more precise and readable, which means it has a higher maintenance capability. If you intend to switch from one to the other or are in the stage of choosing between React and Vue, I hope this article gives you a few insights. Thank you for reading!
The Syncfusion React suite offers over 70 high-performance, lightweight, modular, and responsive UI components in a single package.
The Syncfusion Vue UI components library is the only suite you will ever need to build an app. It contains over 65 high-performance, lightweight, modular, and responsive UI components in one package.
For questions, you can contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!