You can either roll the dice or make a considered choice

Written by El_Nino | Published 2017/08/01
Tech Story Tags: javascript | vuejs | react | vanillajs | framework

TLDRvia the TL;DR App

Choosing the right JavaScript (JS) framework for your project can be quite a daunting task in the current web development landscape. There are endless possibilities, and every framework has its own philosophy on how to tackle the challenges presented by modern web development. In this article, I will discuss features that we considered essential by comparing two frameworks, React and Vue. These essential features can vary massively depending on the project and personal preference, so I’d recommend that you analyse your project’s needs and developer’s preferences and base your decision on that analysis.

Data binding

Data binding lets you connect your application’s logic to your user interface. It allows you to set a value in your HTML template and automatically update this value if your data changes. Data can be bound in a one-way or two-way manner. One-way data binding is when a state change should update a value inside your template. If a template should also be able to change the state value, e.g., an input field’s value, you’d have to use two-way data binding.

Vanilla JavaScript

Displaying a value inside an HTML element and updating the display as soon as this value changes can be quite cumbersome to do in Vanilla JS. It is often done using an Observer pattern, subscribing to data changes and setting the value on the element. This gist by Austin Hyde gives a great explanation on how this can be achieved using a single function. However, to bind values to your interface, you will need to perform some additional work. You will have to get the element reference (e.g., by using getElementById) and call the function to initialise the binding.

function bindValue(input, observable) {var initial = observable();input.value = initial;observable.subscribe(function(){ input.value = observable(); });

var converter = function(v) { return v; };if (typeof initial == 'number') {converter = function(n){ return isNaN(n = parseFloat(n)) ? 0 : n; };}

input.addEventListener('input', function() {observable(converter(input.value));});}

React

In React, data only flows one way: from parent to child. This approach results in the parent state being the source of truth. However, many applications use some form of two-way data binding at some point. An example of this is working with forms, where you often want the state to represent an input’s value. To achieve this in React, you will have to listen for change events and update the state via a callback function. This requires you to write additional code and logic.

Vue

Vue provides a set of different data binding syntaxes. The most basic way is to use double curly brackets (Mustache) syntax. By default, this will bind data in a two-way manner and interpret the values as plain text. Inside of these mustaches, basic JS expressions can be used to evaluate a particular value. However, the mustaches cannot be used inside attributes. To solve this problem, Vue provides a set of so-called directives. Directives are unique attributes that can be used to specify the behaviour of Vue’s data binding. For example, you can add v-once to set one-way data binding, v-html to interpret the value as HTML or use v-bind:<attr> to bind a value to the specified HTML attribute.

Syntax

All JS frameworks have to comply with the standard JS syntax. However, the speed at which new versions are rolled out is quite low, meaning that you often cannot use the latest platform features. To solve this, build tools like Babel have been developed. These tools allow you to develop your application using the newest syntax and convert it to an older syntax for compatibility with older browsers. They are usable with nearly all modern web development frameworks, but every framework also introduces its own syntax for building components, working with plugins and templating, for example.

React

The most basic React component consists of an ES6 class with a render function. The render function returns JSX (a preprocessor step for adding XML syntax to JavaScript) which is then rendered to the screen as HTML. Every component has access to a set of lifecycle callbacks to be able to hook into the React lifecycle and perform specific tasks when an element enters a particular step within the lifecycle.

class Welcome extends React.Component {constructor(props) {super(props);

//Set the initial state of the componentthis.state = {variable: "Hello World!",clicked: false}}

//On click handler for the buttononClick() {this.setState({clicked: true});}

//The render function containing the templaterender() {return (<div>//Only show the text if the button has been clicked.{this.state.clicked &&<div>{this.state.variable}</div>}

    <button onClick={this.onClick.bind(this)}>Click me!</button>  
  </div>  
);  

}}

Vue

The syntax for creating a Vue component is quite straightforward. You can create a .vue file which contains an HTML template surrounded by <template> tags and a <script> tag containing the JS logic. By default, a Vue component exports a JavaScript object containing specific fields for specific information. Using a decorator, this can be adjusted to be able to handle ES6 class syntax. Personally, I prefer to separate my templates and logic into separate files, which is a piece of cake in Vue. Simply replace the contents of the <script> tag with a reference to a JS file like you would in plain HTML/JS and you’re done.

<template><!-- Only show the text if the button has been clicked. --><div v-if="clicked">{{variable}}</div><button v-on:click="onClick">Click me</button></template>

<script>//Decorator to be able to use the ES6 class syntax@Componentexport default class HelloWorld extends Vue {//Name of the componentname = 'HelloWorld';

// A variable containing an arbitrary valuevariable = "Hello World!";

//True if the button has been clickedclicked = false;

//On click handler for the buttononClick() {this.clicked = true;}}</script>

Maturity

Depending on your use case, the maturity of a framework can be critical. For personal projects, it doesn’t matter that much. Use whatever you want to learn more about or find interesting. For production apps, however, it is more important to know that a framework is a bit more mature to reduce the chance of breaking changes or lack of commitment from the development team. The community around a framework often increases with maturity, resulting in an extensive knowledge base with components, libraries, plugins and solutions to bugs. All of this makes the development experience a lot more pleasant.

Conclusion

Depending on your project’s needs and specifications, the answer to what framework you should choose can change dramatically. If there is a single feature (e.g., you only need data binding) that you need for your web app, Vanilla JavaScript is excellent. It keeps your codebase small and limits the number of dependencies. This, in turn, decreases the likelihood of entering JavaScript’s dependency hell. If you want to build a full-fledged progressive web app or single page application, however, creating it using vanilla Javascript is a lot of additional work. In this situation choosing a framework that already offers all of the features you might need is ideal as you can just start building the functionality that makes your project unique.

However, there is no single answer to what framework you should use. As mentioned before, this highly depends on your project so this is a question only you can answer.

By Rick. Rick is a developer at El Niño who is passionate about Android and always makes considered choices.


Published by HackerNoon on 2017/08/01