React vs Vue: my personal point of view
Tags: vue, react, javascript, showdev
Published: 2019-11-02 20:48:56

Being a Front End developer I've got the luck to have worked with both React and Vue. I have worked with React for almost one year (2017-2018) and I've been working with Vue since July 2018 (when I joined [MotorK](https://www.motork.io)).

This post won't be about which could be the best between React and Vue, but it will be about my personal point of view. I don't write what I prefer at the end of the post, but I'm going to do it now; at the beginning.

My favourite one is 🥁🥁🥁 **Vue!** And I'm going to explain to you why.

## Table of Contents
1. [Separation of concerns](#separation-of-concerns)
2. [No JSX](#no-jsx)
3. [Computed props](#computed-props)
4. [Mixins](#mixins)
5. [Ecosystem](#ecosystem)

### Separation of concerns
One of the best features of Vue is the "separation of concerns" of Single File Components (SFC). In Vue's SFC there are three available blocks: `<template>`, `<script>` and `<style>` whose the goal is to split the HTML, the JavaScript and CSS code.

So, what you could have in a SFC is something like:
```html
<template>
    <section class="awesome-vue-component">
        <header class="awesome-vue-component__header">{{header}}</header>
        <div class="awesome-vue-component__body">{{body}}</div>
        <footer class="awesome-vue-component__header">{{footer}}</footer>
    </section>
</template>

<script>
    export default {
        name: 'AwesomeVueComponent',
        props: {
            header: {
                type: String,
                required: true,
            },
            body: {
                type: String,
                required: true,
            },
            footer: {
                type: String,
                required: true,
            },
        }
    }
</script>

<style lang="scss" scoped>
    .awesome-vue-component {
        &__header { 
            font-size: 18px;
        }

        &__body { 
            font-size: 14px;
        }

        &__footer { 
            font-size: 11px;
        }
    }
</style>
```
The same code in React would be something like:
```jsx
import "awesome-react-component.scss";

class AwesomeReactComponent extends React.Component {
    render() {
        const {
            header,
            body,
            footer
        } = this.props;
        
        return (
            <section className="awesome-vue-component">
                <header className="awesome-vue-component__header">{header}</header>
                <div className="awesome-vue-component__body">{body}</div>
                <footer className="awesome-vue-component__footer">{footer}</footer>
            </section>
        );
    }
}
```
Since React doesn't support blocks, the only way to import SCSS is reading of an external .scss file, which adds a little bit of complexity to the component.

---

### No JSX
As I've already shown you, React doesn't give you the possibility to write a well-easy understandable code. Since it doesn't have blocks, it must mix HTML and JavaScript. This "mixture" is called **JSX** which is a JavaScript's syntax extension for describing UI parts.

*But why I don't like JSX?*
Just let me give you one example:

#### Vue code
```html
<template>
    <section class="posts">
        <section v-for="post in posts" :key="post.id" class="post">
            <header class="post__header">
                <h3 class="post__title">{{post.title}}</h3>
            </header>
            <div class="post__body">{{post.body}}</div>
            <footer class="post__footer">
                <p>{{post.footer}}</p>
            </footer>
        </section>
    </section>
</template>
```

#### React code
```jsx
class Posts extends React.Component {
    render() {
        return (
            const posts = this.props.posts.map( post => {
                return (
                    <section key={post.id} className="post">
                        <header className="post__header">
                            <h3 className="post__title">{post.title}</h3>
                        </header>
                        <div className="post__body">{post.body}</div>
                        <footer className="post__footer">
                            <p>{post.footer}</p>
                        </footer>
                    </section>
                )
            } );
    
            <section className="posts">
                {posts}
            </section>
        )
    }
}
```
I find the Vue's code more readable, clear and easy to understand.
I mean: it's **just HTML** code after all, isn't it?

![Woah](https://giphygifs.s3.amazonaws.com/media/hAK7E1hcIXPgI/giphy.gif)
I know, some of you are thinking: "Hey, you should create a Post component and put the code inside it!" And yes: you're totally right, but the focus of this point is that, using React, you must mix HTML and JavaScript code, which is something I really don't like because it could lead you in writing more bugs.

---

### Computed props
Computed props are another nice Vue's feature. Basically they're function whose the result is **cached** based on their reactive dependencies. 

**... WTF?!**

Ok, let me explain it better.
Computed props are used for wrapping a piece of logic that depends on a reactive data (_props_ or _data_) and they are (re)evaluated only if their reactive dependencies change.

Let me give you a real example:
```html
<template>
    <div class="dummy-vue-component">
        <p>{{greetByMethod()}}</p>
        <p>{{greetByComputed}}</p>
    </div>
</template>

<script>
    export default {
        name: 'DummyComponent',
        props: {
            name: {
                type: String,
                required: true,
            }
        },
        methods: {
            greetByMethod() {
                return `Hello ${this.name}`;
            }
        },
        computed: {
            greetByComputed() {
                return `Hello ${this.name}`;
            }
        }
    }
</script>
```
`greetByMethod()` and `greetByComputed()` will produce the same result, with an important difference: the first one is called everytime the UI gets a re-render, the second one is re-evaluated only if `this.name` changes. So, as you can easily understand, computed props are better and more performant.
You should use a method only if you need to pass a parameter from the view; otherwise go with a computed.

**N.B.** <u>When you use computed props, you have to get rid of</u> `()`, <u>otherwise Vue will run them like methods and your app won't work anymore</u>.

---

### Mixins
Mixins allow you to share pieces of code (props, computed, methods and life-cycle methods) among components. Basically it consists in a JavaScript object to inject into a Vue's instance.
```javascript
/**
 * @mixin InputMixin
 */
export const InputMixin = {
    data() {
        return {
            value: ''
        }
    },
    props: {
        id: {
            type: String,
            required: true,
        },
        name: {
            type: String,
            required: true,
        }
    },
    computed: {
        getUniqueKey() {
            return `${this.name}-${this.id}`
        }
    }
}
```
This is a simple mixin which can be injected into a component in this way:
```html
<template>
    <div class="input-text">
        <input
            v-model="value"
            :id="getUniqueKey" 
            :name="name" 
            type="text" />
    </div>
</template>

<script>
    import { InputMixin } from './base-mixin';

    /**
     * @mixes InputMixin
     */
    export default {
        name: 'InputText',
        mixins: [
            InputMixin
        ]
    }
</script>
```
The `InputText` component will contain the whole `base-mixin.js` content: data, props and computed.

If you have a different component, which needs of same props, computed and data, you can use this mixin and avoid the code duplication. Cool, isn't it?

**N.B.** <u>Since mixins add complexity to the component, you should use the [@mixes JSDoc](https://jsdoc.app/tags-mixes.html) tag to indicate that the component is using a mixin</u>.

---

### Ecosystem 

Another point in favor of Vue is its incredible Ecosystem.
I like to define Vue as "micro-framework" because it can be extended with other libraries like [Vuex](https://vuex.vuejs.org/) and [Vue Router](https://router.vuejs.org/). These two libraries are maintained by Vue's core team and this is something that React doesn't have. Actually also React can be extended installing [Redux](https://redux.js.org/) and [React Router](https://reacttraining.com/react-router/web/guides/quick-start), but they are projects not managed by the React team which means they are unofficial. 
This possibility shouldn't be either ignored nor underrated, because having a libraries handled by the same team it's really important to have a more stable application.

---

### Follow me on

- 👾 [GitHub](https://github.com/Sanfra1407)
- 📷 [Instagram](https://www.instagram.com/Sanfra1407/)

_If you liked the post, you might offer me a_ ☕️ _on [PayPal](https://www.paypal.me/giuseppesanfrancesco)._ 🙂

---