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