Have you ever heard about Vue functional components?
Tags: vue, javascript, webdev, showdev
Published: 2019-08-14 20:45:22

First of all: welcome to my blog! This is my first post and I want to greet you and say a big thanks for coming here!

So, let's go forward with the real topic of this post.

# Table of Contents
1. [What is a Vue component?](#what-is-a-vue-component)
2. [Functional component](#functional-component)
3. [How can I write a functional component?](#how-can-i-write-a-functional-component)
4. [TL;DR](#tldr)

## What is a Vue component?
Basically a component is a reusable [Vue instance](https://vuejs.org/v2/guide/instance.html) with its own state, props, computed props, methods and lifecycle.

Cool features, right? Yes, they are... But try to ask to yourself: "_Do I always really need of all these features? Is it always necessary to have reactive data and the whole [component's lifecycle](https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram)?_"
The answer to all these questions is: **No, you don't**.

Sometimes you just need to have a component whose main gol is to render something.

I know, now you're asking to yourself: _"Could I use a normal component to do that?"_
The answer is: **Yes, you can**.

But, now, let me ask you a question: "_Why should you use a normal component for doing that when you can use a **functional component**_?"

## Functional component
A functional component is, basically, an instanceless component without the lifecycle. Nothing else. It's just a simple function whose goal is to render some data.

For this reason you can also call it _**presentational component**_ or _**dumb component**_.

Since this kind of components don't have instances, they are faster, **lighter** and rendered once. As you can see I've written **lighter** because, without the whole lifecyle and the reactivity system, the final bundle is lighter, which means:

- less JavaScript code to parse;
- less memory to handle.

All this stuff gives to your applications **better performances** and browsers will be grateful to you.

## How can I write a functional component?
I'm pretty sure, at this point, you have this question spinning around in your mind. I want to be as clear as possible, so I'll answer you with some code.

What I'm going to do is to code a _normal component_ and transform it into a _functional component_.

### Normal component
```html
<template>
  <div class="smart-component">
    <span class="smart-component__prop">{{foo}}</span>
    <span class="smart-component__prop">{{bar}}</span>
  </div>
</template>

<script>
  export default {
    name: "SmartComponent",
    props: {
      foo: {
        type: String,
        required: true
      },
      bar: {
        type: String,
        required: false,
        default: "Default value"
      }
    }
  };
</script>
```

Cool, isn't it? But do you know what happen each time the `SmartComponent` is instantiated?

Basically Vue [creates its instance](https://vuejs.org/images/lifecycle.png), adds reactivity and mount the component. All useless stuff, since the `SmartComponent` is not going to use reactivity. And, as I've already said, the final bundle will be heavier.

**Let's rewrite it in the _functional way_**.

### Functional component
```html
<template functional>
  <div class="dumb-component">
    <span class="dumb-component__prop">{{props.foo}}</span>
    <span class="dumb-component__prop">{{props.bar}}</span>
  </div>
</template>

<script>
  export default {
    name: "DumbComponent",
    props: {
      foo: {
        type: String,
        required: true
      },
      bar: {
        type: String,
        required: false,
        default: "Default value"
      }
    }
  };
</script>
```

That's all. Nothing special. As you can see, I've only changed a couple of things:

- I've added the `functional` keyword to the template block;
- I've prepended the `props` keyword to `foo` and `bar` props.

#### The functional keyword
Well, as you can easily guess, the `functional` keyword is used to say to Vue: "_Hey, I'm going to write a functional component! Don't overload it adding the whole lifecycle and the reactivity; I don't need them!_"

#### The props keyword
Since functional components don't have an instance, the `this` keyword will be `undefined`. So, to read props, you need to prepend the `props` keyword to each prop.

![Woah](https://giphygifs.s3.amazonaws.com/media/hAK7E1hcIXPgI/giphy.gif)

I know, I know... You're asking to yourself: "_WTF? I don't see any `this` before `SmartComponent` props!_"
The reason is that Vue automatically binds `props`, `methods`, `computed` and `$options` objects to the component instance.
So, basically, in this scenario `{{foo}}` and `{{bar}}` are short versions of `{{this.foo}}` and `{{this.bar}}`.
**Keep in mind: this works ONLY within the `<template>` block; in the `<script>` block you MUST put the `this` keyword before props, methods, computed and $options, otherwise you'll get an error.**

N.B. There is another way to write functional components and it's with the usage of _render functions_, but I'll write a more detailed post about them.

## TL;DR
When you don't need to have a reactive state and the whole component lifecycle, for better performances, you **should** use functional components.

---

### 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)._ 🙂

---