Vue Composition API vs. React Hooks
Tags: webdev, javascript, react, vue
Published: 2022-07-21 11:17:27

---
title: Vue Composition API vs. React Hooks
published: true
date: 2022-07-21 10:00:16 UTC
tags: webdev, javascript, react, vue
canonical_url: https://www.syncfusion.com/blogs/post/vue-composition-api-vs-react-hooks.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zgemwrehayjtbxcorxb5.png
---

[React Hooks](https://reactjs.org/docs/hooks-intro.html "Introducing React Hooks") were introduced with the React 16.8 update, and since then, they have become a necessity for [single-page applications](https://en.wikipedia.org/wiki/Single-page_application "Wikipedia page 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](https://vuejs.org/ "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.

## Way of Rendering

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.

```js
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;
```

![Way of rendering in React Hooks](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Way-of-Rendering.png)In Vue 3, a component is an object, and it can be defined with the **setup()** method introduced with the Composition API. You may feel that the React functional component’s body and Vue’s **setup()** operation work similarly. But the **setup()** method is only executed once, and it acts as an entry point to the Composition API. With the help of that, we can define a state, and this avoids recreating the state with every call.

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.

```html
<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>
```

## ![Way of Rendering price value](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Way-of-Rendering-price-value.png)Reactive Objects

**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.

```js
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.

```html
<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>
```

![Implementing Reactive Objects](https://www.syncfusion.com/blogs/wp-content/uploads/2022/07/Reactive-Objects.png)  
React has defined some rules for utilizing Hooks:

- Hooks must be called on the top level of React function components.
- Hooks should not be called inside loops, conditions, or nested functions.

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.

## Aesthetics and Readability

### Defining the state

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.

```js
// 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.

### Changing the state

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.

```js
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.

```js
<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.

## Handling Side Effects

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.

```js
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.

```html
<script>
import { watchEffect, ref, defineComponent } from "vue";
export default defineComponent({ 
 setup() { 
   const price = ref(100); 
     watchEffect(() => 
       console.log(price.value)) 
   ); 
   return { 
     price 
   }; 
 },
});
</script>
```

### Key differences:

- **useEffect**  — We can tell when the effects will be active by manually adding dependencies. **useEffect** should be called inside the component.
```js
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]);
```
- **watch**— This works very similar to **useEffect**. We have to tell it when to run the callback function.
```js
//The callback is called whenever `refA` changes.
  watch(refA, () => {
    console.log(refA.value);
  });
```
- **watchEffect**  — With this, we don’t need to add specific dependencies manually. It will run the callback function whenever the reactive variables we use inside it change. And **watchEffect** works outside of a Vue component.
```js
//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.

## Final Thoughts

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](https://www.syncfusion.com/react-ui-components "React UI Components Library") suite offers over 70 high-performance, lightweight, modular, and responsive UI components in a single package.

The Syncfusion [Vue UI components library](https://www.syncfusion.com/vue-ui-components "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](https://www.syncfusion.com/forums "Syncfusion support forum"), [support portal](https://support.syncfusion.com/ "Syncfusion support portal"), or [feedback portal](https://www.syncfusion.com/feedback "Syncfusion Feedback Portal"). We are always happy to assist you!