React vs Vue: Programming Experience

Shashank Jain
6 min readAug 26, 2018

--

After working with Vue for nearly an year, I recently moved to React. The experience working with both was quite different. While Vue was much simpler, React was more fun to work with.

There are ample articles that compare React and Vue on statistical basis (speed, size, support, etc.), so I would not touch those. I have added links to a few such articles at the end of this post. I would compare the two purely on coding experience point of view.

React: JSX is more intuitive

Mixing HTML and JavaScript has been a hot topic of discussion since the onset of React. Personally, I too wasn’t a big fan of this idea until I started working in React.

After I began using JSX, I felt it was easier and more intuitive — writing HTML logic right there in your code made it more natural to think and manage code.

HTML was not designed for logic, so putting directives like v-for, v-if, etc. is kind of a hack.

For example, look that the following Vue code where I have to render a placeholder row if there is no data in the table:

Compare this to React code:

What you can see is with JSX, we can use familiar constructs like, if statements, functions, loops, etc. which looks much more natural than Vue code.

Note: Vue also has added support for JSX: https://vuejs.org/v2/guide/render-function.html#JSX. However, its not that popular in Vue ecosystem.

React: One-Way data binding to the rescue

One of the most important factors, which is often ignored while comparing Vue (or Angular) and React, is — Vue has two-way data binding, while React has one-way data binding.

On the surface, two-way data bindings sounds better (and cooler), but more often than not — it results in unexpected behaviours and performance issues.

As aptly described by Jing Chen, creator of Flux, in this video:

With two-way data binding, there is just an explosion of command flows, and it is hard to tell if there is any infinite loop that might be causing a cascading effect.

For example, look that following Vue code:

I am trying to make a date-picker component using an existing plugin. This code can result in an infinite loop because of two-way data binding:

  • When I supply 2018–02–02 as value to the component, it converts it into moment object and passes it to the date-picker.
  • Since, I updated the date-picker’s value, it’s update event gets fired.
  • This results in component emitting the date again to update the model. However, this time updated date is something like: 2018–02–01T18:30:00+00:00. Observe that this date is different from the date supplied.
  • Since, we got back a different date from the date-picker, we will end up updating the date again in the watcher, and thus resulting in an infinite loop.

This an actual component I had used in a project. However, I have removed all the extra conditions and checks I had to put in order to prevent an infinite-loop. Add to this the amount of time I had to spend debugging the code.

Update 1: With feedback from comments, I have added more explanation to this example, at the end of this article.

React: Better Code Management

In Vue, standard way to write components is using .vue files, which combines HTML, CSS and JavaScript in same file.

In React, there is no such standard way. React components are regular JavaScript functions/classes and you can organise them the way you want.

Absence of a standard way provides freedom which leads to innovation. Paradigms such as Presentational and Container Components, and Styled Components, are a result of this.

Just imagine, you have a large application with hundreds of components — would you want to be restricted or be free to find the best way to organise your code?

One might argue that Vue is quite flexible too and .vue components are not a required way to write components. However, when you are dependent on community for support, other ways hardly matter. You would almost always go by the recommended way.

Vue: Easier to get started

Recently, I had to implement sorting of rows in an HTML table on the click of the table’s headers. I just included Vue.js on the page, attached it to the table element, implemented sorting in JavaScript, and Vue automatically rendered sorted table.

I could not have achieved this easily with React. Either I would have to write the React.createElement hell myself, or, setup a development environment with webpack to compile babel.

Conclusion

Personally, I find it more fun to work with React. With it, I can let my imagination run wild. Although Vue is much easier to get started and can be easily plugged into a part of a page, for bigger applications React is more suitable.

Update 1: The example given is not a direct example of two-way data-binding, rather of a component trying to implement it, i.e., trying to keep the v-model, provided to the component, in sync.

In the example, consider the following usage of the component:

<DatePicker v-model="date" />

Here essentially, I want the date variable to be in sync. That means:

  • If I update date within the parent component (for example, I choose a start date for an event from a calendar plugin), I want the contained date-picker to update.
  • If I select a new date from date-picker, I want the date to get updated.

Following diagram will make it more clear:

Two-way binding expected flow

Compare this to one-way data-binding flow in React:

One-way data binding flow

While, this may also look like two-way flow, note that value from component to plugin is passed via value prop, while from plugin to component via onChange event. So, in our example:

  • I provide 2018-02-02 as value. This, will be passed to plugin in componentWillReceiveProps and datepicker value will get updated.
  • Yes, this will fire the dp.change event which will fire onChange event.
  • However, in onChange, we will not update the value prop again which prevents circular loop.

Yes, this is also possible in Vue.

However, what I am trying to emphasise is that, in Vue, you expect components to be two-way binded. When working in a team, if you implement a different flow than this, it can lead to confusion and bugs.

Have a look at popular Vue plugins: vue-select, vue-slider, vue-datetime, etc. All of them are implemented with two-way binding using v-model.

Vue also has one-way binding

Yes, it does. However, if you look at documentation, and the intro video, you can see that most of the times two-way binding is used. Most of the developers would not know or use one-way binding in Vue.

For your reference, I add some other articles that compare React and Vue on statistical factors:

--

--