<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: VueTraining.net</title>
    <description>The latest articles on DEV Community by VueTraining.net (@vuetraining).</description>
    <link>https://dev.to/vuetraining</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F440628%2Fb2c7fccf-42ab-4d44-add9-e56b27e3e4a2.png</url>
      <title>DEV Community: VueTraining.net</title>
      <link>https://dev.to/vuetraining</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vuetraining"/>
    <language>en</language>
    <item>
      <title>React Hooks API vs Vue Composition API, as explored through useState</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Wed, 19 Aug 2020 04:26:10 +0000</pubDate>
      <link>https://dev.to/vuetraining/react-hooks-api-vs-vue-composition-api-as-explored-through-usestate-32k1</link>
      <guid>https://dev.to/vuetraining/react-hooks-api-vs-vue-composition-api-as-explored-through-usestate-32k1</guid>
      <description>&lt;p&gt;You've read plenty of high-level, abstract articles about React vs Vue, about Hooks API vs Composition API.&lt;/p&gt;

&lt;p&gt;This article is different.&lt;/p&gt;

&lt;p&gt;This is exploring &lt;em&gt;one specific feature&lt;/em&gt;, React's &lt;code&gt;useState&lt;/code&gt; hook, and seeing how we can accomplish the equivalent functionality with Vue's Composition API.&lt;/p&gt;

&lt;p&gt;While we're exploring, we're going to uncover what I believe are two of the core philosophical differences between React and Vue, and how that effects every single facet of their APIs.&lt;/p&gt;

&lt;p&gt;I'm going to offer my opinion on how each framework stacks up, but I'm also going to give you side-by-side code comparisons so you can make your own decision.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article presumes familiarity with either React or Vue.  If you want something for a team completely new to frontend development, &lt;a href="https://www.vuetraining.net/react-vs-vue-guide-signup" rel="noopener noreferrer"&gt;sign up for my newsletter&lt;/a&gt; and you'll be the first to know when that's ready.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  useState and the Click Counter
&lt;/h1&gt;

&lt;p&gt;We're going to start with the basic example shown in the &lt;code&gt;useState&lt;/code&gt; documentation.  You click a button which adds 1 to a counter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvue-screencasts-uploads.s3-us-west-2.amazonaws.com%2Fblog-images%2Fuse-state-click-counter-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvue-screencasts-uploads.s3-us-west-2.amazonaws.com%2Fblog-images%2Fuse-state-click-counter-2.png" alt="Code for the click counter app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those on smaller screens, don't worry - we'll show a larger, copy-pastable version of the code right before we start talking about the mechanics of each component.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our plan is to spend quite a bit of time dissecting this example - including some design choices that aren't directly related to &lt;code&gt;useState&lt;/code&gt; - then tackle a more complicated example with &lt;code&gt;useState&lt;/code&gt; to see how both frameworks' solutions bend and break with increased requirements.&lt;/p&gt;

&lt;p&gt;Some quick notes before we go farther:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm relatively new to React, so when possible I'm going to rip code straight from documentation and well-regarded tutorials.  If there's a better way of doing things, tell me in the comments.&lt;/li&gt;
&lt;li&gt;We're "flipping" the script and template tags for Vue's Single File Components, so the code is easier to compare to React.  Normally the template tag would go first, then the script tag (and then the style tag, which we've left off of the screenshots)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, those caveats done, let's compare these two pieces of code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aesthetics and Readability
&lt;/h3&gt;

&lt;p&gt;Here's the code comparison for the Click Counter again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvue-screencasts-uploads.s3-us-west-2.amazonaws.com%2Fblog-images%2Fuse-state-click-counter-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvue-screencasts-uploads.s3-us-west-2.amazonaws.com%2Fblog-images%2Fuse-state-click-counter-2.png" alt="Code for the click counter app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first thing you'll notice is that there are more lines of Vue code, while React has longer individual lines.  Personally, I find the React code on this example a bit more aesthetically pleasing because I have a personal vendetta against extra lines and boilerplate code, but the Vue code is a bit easier to digest.&lt;/p&gt;

&lt;p&gt;This is especially true with how they've differentiated the pure Javascript portion of the code from template portion of the code.  Vue has a &lt;code&gt;script&lt;/code&gt; tag and a &lt;code&gt;template&lt;/code&gt; tag which clearly differentiate them.  In React, they save a few lines by putting it all in one function and asking you to remember that the setup goes in the main body of the function and the template goes in the return value (except when it doesn't).&lt;/p&gt;

&lt;p&gt;I think in general, Vue's boilerplate can look bad &lt;em&gt;for very small examples&lt;/em&gt; like the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// React&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// Vue&lt;/span&gt;
&lt;span class="nf"&gt;setup &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;However, if you add a couple more pieces of state, we can see that Vue's code starts looking like the cleaner option.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// React&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// Vue&lt;/span&gt;
&lt;span class="nf"&gt;setup &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;count2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;count3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And a huge chunk of the boilerplate can be completed by starting your file with the &lt;code&gt;vbase-3&lt;/code&gt; auto-complete in VSCode, so with Vue you'll end up typing about the same number of characters or less.&lt;/p&gt;

&lt;p&gt;There's also &lt;a href="https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-script-setup.md" rel="noopener noreferrer"&gt;an RFC in progress&lt;/a&gt; for reducing that boilerplate significantly.&lt;/p&gt;

&lt;p&gt;Now let's look at &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;ref&lt;/code&gt; directly.  &lt;/p&gt;

&lt;h2&gt;
  
  
  useState vs ref
&lt;/h2&gt;

&lt;p&gt;They're not exactly equivalent, but &lt;code&gt;ref&lt;/code&gt; (short for "reactive reference") can easily be used to accomplish the same functionality as &lt;code&gt;useState&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's first look at how &lt;code&gt;useState&lt;/code&gt; is used in React.&lt;/p&gt;

&lt;h2&gt;
  
  
  useState
&lt;/h2&gt;

&lt;p&gt;Here's the code for the React component.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;clicked&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;times&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;me&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;useState&lt;/code&gt; is a function that takes one argument, which is the initial state.  It returns an array with two values - the initial state, and then a function which can be used to change the state.&lt;/p&gt;

&lt;p&gt;You can name the two items in the array anything you want, and you can handle the return array any way you want, but I personally don't see why you'd do anything except the following one-liner that uses array destructuring.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFoo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But if you want to go nuts and name your stuff in a different (worse) manner, React's not going to stop you:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// please don't do this&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myUseStateExample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myUseStateExample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aGoodWayToChangeFoo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myUseStateExample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, presuming we're using the standard naming, we can then use &lt;code&gt;count&lt;/code&gt; for the count, and &lt;code&gt;setCount(newValue)&lt;/code&gt; to change the value of &lt;code&gt;count&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You clicked &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; times&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Click me
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The question I had, as a relative React outsider, is this: why have a variable that can't be changed, and then a function whose sole purpose is to change that variable?  Why not just let &lt;code&gt;count = newValue&lt;/code&gt; be what sets the count?&lt;/p&gt;

&lt;p&gt;The reason, without getting too into the weeds, is that React's component lifecycle and State APIs - which were created before React Hooks and are what the Hooks are "hooking" into - require it.  If you just use &lt;code&gt;count = newValue&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt; won't update properly everywhere it's used because React doesn't know that anything's changed.  In general, it appears that you won't have to think about the component lifecycle or the old APIs much while using the Hooks API... unless you're curious enough to dig into why some hooks work the way they do.&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;Yeah, that's close. Hooks let you "hook into" the React component lifecycle and state APIs without creating a class or using the methods, but all the ideas that make React React are still the same.&lt;/p&gt;— Go JS! (@JS_Cheerleader) &lt;a href="[https://twitter.com/JS_Cheerleader/status/1293424865165230080?ref_src=twsrc^tfw](https://twitter.com/JS_Cheerleader/status/1293424865165230080?ref_src=twsrc%5Etfw)"&gt;August 12, 2020&lt;/a&gt;
&lt;/blockquote&gt; 
&lt;h2&gt;
  
  
  ref
&lt;/h2&gt;

&lt;p&gt;Here's the code for the Vue component:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setup &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;You clicked &lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt; times&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"count++"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Click me
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In Vue, we use &lt;code&gt;ref&lt;/code&gt; to create a reactive reference to a value.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="nf"&gt;setup &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, in our template, we can display and set &lt;code&gt;count&lt;/code&gt;, and it will act like a normal Javascript variable.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;You clicked {{count}} times&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"count++"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click me
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note the simplicity of this. We can just use &lt;code&gt;count++&lt;/code&gt;, or &lt;code&gt;count += 1&lt;/code&gt;, or any number of other easy Javascript shortcuts, rather than declaring a new function and feeding a new value into &lt;code&gt;setCount&lt;/code&gt; (&lt;code&gt;() ⇒ setCount(count + 1)&lt;/code&gt; vs &lt;code&gt;count++&lt;/code&gt;). Behind the scenes, Vue turns that one line of Javascript (&lt;code&gt;count++&lt;/code&gt;) into an executable function that's run when the click event is fired. Behind the scenes, Vue updates every instance of &lt;code&gt;count&lt;/code&gt; when we run &lt;code&gt;count++&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One reason it can do this is because it's using the custom event listener directive &lt;code&gt;@click&lt;/code&gt;.  The custom syntax allows for simpler code than if we had to use &lt;code&gt;onClick&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I really like the simple code created by Vue's approach. By hiding the layers of complexity, we can get something that's easy to write and easy to read.&lt;/p&gt;

&lt;p&gt;But you may be curious about that complexity. How does Vue know to change every instance of &lt;code&gt;count&lt;/code&gt; when we run &lt;code&gt;count++&lt;/code&gt;? If React has to use &lt;code&gt;setCount&lt;/code&gt;, why doesn't Vue have to do something similar?&lt;/p&gt;

&lt;p&gt;The short answer is that Vue &lt;em&gt;does&lt;/em&gt; do something similar, but they hide it from you so you don't have to think about it - that's one more issue off your plate.&lt;/p&gt;

&lt;p&gt;Of course, that complexity-hiding isn't always perfectly seamless.  For example, let's look at how we set &lt;code&gt;count&lt;/code&gt; within our script block.  Now we have to use &lt;code&gt;count.value&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="nf"&gt;setup &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numAdded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;numAdded&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;addValue&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The reason is that Vue's reactivity system requires an object in order to function properly, so &lt;code&gt;ref&lt;/code&gt; creates an object like &lt;code&gt;{value: 0}&lt;/code&gt;.  In the template, Vue hides this complexity from you and lets you access and change &lt;code&gt;count&lt;/code&gt; without specifically referencing the &lt;code&gt;value&lt;/code&gt; property, but in the script block you no longer have this shortcut.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing the code so far
&lt;/h2&gt;

&lt;p&gt;So far, while I personally prefer the Vue code, objectively they're neck and neck.&lt;/p&gt;

&lt;p&gt;Both are fairly straightforward once you start playing around with them, with a few slight paper cuts on either side.&lt;/p&gt;

&lt;p&gt;React has fewer lines in the setup code, but there's the inconvenient separation between &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;setFoo&lt;/code&gt;, and the whole naming foot-gun, that makes the API less easy to use than it could be.&lt;/p&gt;

&lt;p&gt;Vue has  some great conveniences (compare &lt;code&gt;@click="count++"&lt;/code&gt; to &lt;code&gt;onClick={() =&amp;gt; setCount(count + 1)}&lt;/code&gt;), but slightly more starter boilerplate, and you have to remember to use &lt;code&gt;count.value&lt;/code&gt; instead of &lt;code&gt;count&lt;/code&gt; while in the script block.&lt;/p&gt;

&lt;p&gt;The big difference I see, philosophically, is that&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React wants their APIs to be "pure functional code" and close to basic Javascript,&lt;/strong&gt; even if it means foregoing solutions that are more convenient for the developer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vue wants their APIs to be easy to write and read,&lt;/strong&gt; even if it means custom syntax and slightly more starter boilerplate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see how those philosophical differences inform a more complex case.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reactive Objects
&lt;/h1&gt;

&lt;p&gt;In this example, we're going to be using a short form that has two inputs - first name and last name.&lt;/p&gt;

&lt;p&gt;This particular example was taken from &lt;a href="https://www.youtube.com/watch?v=-3lL8oyev9w&amp;amp;list=PLC3y8-rFHvwisvxhZ135pogtX7_Oe3Q3A&amp;amp;index=4" rel="noopener noreferrer"&gt;Codevolution's wonderful Hooks series on YouTube&lt;/a&gt;, and I then created a Vue version that did the same thing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvue-screencasts-uploads.s3-us-west-2.amazonaws.com%2Fblog-images%2Fuse-state-form-code.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvue-screencasts-uploads.s3-us-west-2.amazonaws.com%2Fblog-images%2Fuse-state-form-code.png" alt="Code comparison for form component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, let's explore the React version&lt;/p&gt;

&lt;h2&gt;
  
  
  useState and objects
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your first name is - &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your last name is - &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Our first line is pretty much the same as last time - we get &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;setName&lt;/code&gt; from &lt;code&gt;useState&lt;/code&gt;, and feed in a default value.&lt;/p&gt;

&lt;p&gt;Then when we're displaying the first name and last name, it's also pretty much the same - we use &lt;code&gt;{name.first}&lt;/code&gt; and &lt;code&gt;{name.last}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Where it gets tricky is in the input.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The input has a &lt;code&gt;value&lt;/code&gt;, which is &lt;code&gt;{name.first}&lt;/code&gt;.  That's straightforward enough.&lt;/p&gt;

&lt;p&gt;Then we have &lt;code&gt;onChange&lt;/code&gt;.  It uses the native &lt;code&gt;onChange&lt;/code&gt; event listener, which takes a function.  That function has one argument, an event.  You can use &lt;code&gt;.target.value&lt;/code&gt; on that event to get the input's new value.  Then you splat &lt;code&gt;...name&lt;/code&gt; in front of that to turn it into the object that &lt;code&gt;setName&lt;/code&gt; wants.&lt;/p&gt;

&lt;p&gt;These lines are... fine, I guess. Once you dig into them you can see what everything's doing, and it's using native Javascript and html syntax, so you don't have to learn any new syntax if you already have a firm grasp of those technologies.  But there's sure a lot of &lt;em&gt;noise&lt;/em&gt; and it's easy to mix things up.&lt;br&gt;
Here's an easy error to make:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Can you guess what happens with this code?&lt;/p&gt;

&lt;p&gt;Well, &lt;code&gt;setName&lt;/code&gt; completely replaces the &lt;code&gt;name&lt;/code&gt; with whatever argument it's given, so that means that the code above will erase the value of &lt;code&gt;name.last&lt;/code&gt; and any other key on the &lt;code&gt;name&lt;/code&gt; object.  You must remember to splat the old object (&lt;code&gt;setName({...name, key: newValue})&lt;/code&gt;) every time.&lt;/p&gt;

&lt;p&gt;Here's another easy error to make:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;newVal&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So with all these easy ways to forget something and screw things up, why is it constructed this way?&lt;/p&gt;

&lt;p&gt;First, let's look at the Vue solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  ref and objects
&lt;/h2&gt;

&lt;p&gt;Here's what the Vue code looks like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
import &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; from 'vue'

export default &lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
      &lt;span class="na"&gt;v-model&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name.first"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
      &lt;span class="na"&gt;v-model&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name.last"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your first name is - &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your last name is - &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;template&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;ref&lt;/code&gt; works the same as last time (but remember: if you use it in the script, you have to do &lt;code&gt;name.value.first&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Using it in the template also works the same as last time.&lt;/p&gt;

&lt;p&gt;And the input tag is... very simple.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;v-model&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name.last"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Honestly, it could just be&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;v-model&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name.last"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, so simple.&lt;/p&gt;

&lt;p&gt;All you have to know about &lt;code&gt;v-model&lt;/code&gt; is that it acts like a "two-way binding".  That means that, whenever the input changes, &lt;code&gt;name.last&lt;/code&gt; changes.  And whenever &lt;code&gt;name.last&lt;/code&gt; changes elsewhere, what's shown in the input changes.&lt;/p&gt;

&lt;p&gt;But notice I said it "acts like" a two-way binding.&lt;/p&gt;

&lt;p&gt;That's because this is just a shortcut for the following code.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name.first"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name.first = $event.target.value"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You'll notice some similarities here to the React code.  We don't have to do the object splat, and this code is simpler in other ways as well, but we're still having a one-way-bound value and an event (&lt;code&gt;@input&lt;/code&gt;) that changes the value based on &lt;code&gt;event.target.value&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing React and Vue on reactive object
&lt;/h2&gt;

&lt;p&gt;This one is a massive win for Vue.&lt;/p&gt;

&lt;p&gt;I mean, look at the difference.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// React&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;({...&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// Vue&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;v-model&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name.first"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The Vue code is clear as day, while the React code has a bunch of moving parts that, let's be honest, will almost always be set up the exact same way unless the coder makes a mistake.&lt;/p&gt;

&lt;p&gt;So why is React like that?&lt;/p&gt;

&lt;p&gt;Three reasons.&lt;/p&gt;

&lt;p&gt;First, Vue is fine introducing new syntax like &lt;code&gt;v-model&lt;/code&gt; or the &lt;code&gt;@input&lt;/code&gt; event listener directive.  React, on the other hand, wants to use native Javascript and Html as much as possible.&lt;/p&gt;

&lt;p&gt;The second is functional purity. &lt;code&gt;setName&lt;/code&gt; replaces the entire object, so we have to splat the old &lt;code&gt;name&lt;/code&gt; object or we'll end up erasing data.  React has made the decision that avoiding mutation is worth the cost of you remembering to do extra steps.&lt;/p&gt;

&lt;p&gt;Third, they want to avoid two-way data binding.&lt;/p&gt;

&lt;p&gt;Two-way data binding, in addition to being Not Functional, has some surprising effects if you misuse it and have multiple layers of two-way data bindings.  It gets harder to track down errors.  We learned this the hard way in the early days of Javascript frameworks.&lt;/p&gt;

&lt;p&gt;So instead of using two-way data binding, React devs now have to specify one-way data binding and an event. Together they're basically two-way data binding with extra steps, but they're not &lt;em&gt;technically&lt;/em&gt; two-way data binding.&lt;/p&gt;

&lt;p&gt;Vue says "why have all the extra steps?" and gives you a nice tool to solve the issue.  Of course, there &lt;em&gt;are&lt;/em&gt; still bad things that can happen with too much two-way data binding, so Vue has some guardrails that prevent you from accidentally making all the old mistakes again.  Generally, you'll use &lt;code&gt;v-model&lt;/code&gt; with low-level form inputs and a few other places where it's convenient, and have custom event code for other components.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Originally I had several more examples, but they ended up going deep into other parts of React and Vue without shedding much more light on the &lt;code&gt;useState&lt;/code&gt; hook... so I'm saving those for my full React vs Vue comparison guide.  Now it's time to review what we've learned.&lt;/p&gt;

&lt;p&gt;Through exploring some uses of &lt;code&gt;setState&lt;/code&gt;, and how to replicate those uses with Vue's Composition API, we've seen pretty clearly a difference of philosophy between React and Vue.&lt;/p&gt;

&lt;p&gt;React values pure functional programming and APIs that are clearly recognizable as Javascript functions (except JSX, and that's still pretty clearly a Javascript function once you know how it works).  This can be quite intellectually satisfying, especially for someone like me who first learned how to code with a LISP dialect.&lt;/p&gt;

&lt;p&gt;Vue values developer ergonomics and making code clear and easy to read, once you learn a couple new pieces of syntax.  This can result in fewer bugs and fewer wasted dev-hours.&lt;/p&gt;

&lt;p&gt;The question you need to ask yourself when choosing one of these frameworks is - which of those sets of values are more important to you?&lt;/p&gt;

&lt;h3&gt;
  
  
  What Now?
&lt;/h3&gt;

&lt;p&gt;To get the full React vs Vue guide for free when it's released, &lt;a href="https://www.vuetraining.net/react-vs-vue-guide-signup" rel="noopener noreferrer"&gt;sign up for my mailing list&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;You can also &lt;a href="https://twitter.com/VueScreencasts" rel="noopener noreferrer"&gt;follow me on twitter&lt;/a&gt;.  While you're there, follow &lt;a href="https://twitter.com/Lachlan19900" rel="noopener noreferrer"&gt;Lachlan Miller&lt;/a&gt; and &lt;a href="https://twitter.com/JS_Cheerleader" rel="noopener noreferrer"&gt;JS Cheerleader&lt;/a&gt;, both of whom shared valuable knowledge that improved this post.&lt;/p&gt;

&lt;p&gt;If you're interested in learning Vue, I've created &lt;a href="https://www.vuetraining.net/" rel="noopener noreferrer"&gt;a training course with hands-on learning and guaranteed results&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're already using Vue successfully and want assistance, I have consulting availability on a limited basis.  &lt;a href="mailto:jeffrey@vuetraining.net"&gt;Contact me for details&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Quick tip: Vue 2 Options API vs Vue 3 Composition Api</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Thu, 13 Aug 2020 17:33:12 +0000</pubDate>
      <link>https://dev.to/vuetraining/vue-2-options-api-vs-vue-3-composition-api-496b</link>
      <guid>https://dev.to/vuetraining/vue-2-options-api-vs-vue-3-composition-api-496b</guid>
      <description>&lt;p&gt;Vue 2's Options API (left)&lt;br&gt;
vs &lt;br&gt;
Vue 3's Composition API (right)&lt;/p&gt;

&lt;p&gt;They look pretty similar here, but Composition API really shines when things get complex.&lt;/p&gt;

&lt;p&gt;Remember to use ".value" for the ref, and to return any variables or functions you'll be using in the template!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LHDcLrHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8qxt7e1xeero0bd2nybw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LHDcLrHi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8qxt7e1xeero0bd2nybw.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Quiz Time! What's Wrong With This "customMax" function?</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Wed, 12 Aug 2020 16:57:27 +0000</pubDate>
      <link>https://dev.to/vuetraining/quiz-time-what-s-wrong-with-this-custommax-function-25m0</link>
      <guid>https://dev.to/vuetraining/quiz-time-what-s-wrong-with-this-custommax-function-25m0</guid>
      <description>&lt;p&gt;Quiz time! What's wrong with our &lt;code&gt;customMax&lt;/code&gt; function?  How do we fix it?&lt;/p&gt;

&lt;p&gt;Hint: check out the second image, where we show "customMax" in use&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dp25Vvjf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gi10m02cp1yb3w2xox8g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dp25Vvjf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gi10m02cp1yb3w2xox8g.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Arrays with Key</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Tue, 11 Aug 2020 16:49:39 +0000</pubDate>
      <link>https://dev.to/vuetraining/arrays-with-key-2ci9</link>
      <guid>https://dev.to/vuetraining/arrays-with-key-2ci9</guid>
      <description>&lt;p&gt;In today’s episode of “wtf Javascript”, we learn you can assign key/value pairs to arrays.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9HVdA9RC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gy9ie67wtlz8ewtq16xa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9HVdA9RC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gy9ie67wtlz8ewtq16xa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>VueJS Tip: Dynamically generate slots for table</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Mon, 10 Aug 2020 17:02:39 +0000</pubDate>
      <link>https://dev.to/vuetraining/vuejs-tip-dynamically-generate-slots-for-table-27d2</link>
      <guid>https://dev.to/vuetraining/vuejs-tip-dynamically-generate-slots-for-table-27d2</guid>
      <description>&lt;p&gt;Want to use slots in your table component, but don't know which columns you'll be using?&lt;/p&gt;

&lt;p&gt;No problem.&lt;/p&gt;

&lt;p&gt;Dynamically generate your slot names using the column name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v4JPGYOT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hdo2ky9a6a1nirnxwhog.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v4JPGYOT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hdo2ky9a6a1nirnxwhog.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Quick VSCode Editor Tip</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Sun, 09 Aug 2020 16:58:21 +0000</pubDate>
      <link>https://dev.to/vuetraining/quick-vscode-editor-tip-e2j</link>
      <guid>https://dev.to/vuetraining/quick-vscode-editor-tip-e2j</guid>
      <description>&lt;p&gt;Need to switch from tabs to spaces?&lt;/p&gt;

&lt;p&gt;Use a regex.&lt;/p&gt;

&lt;p&gt;Find and replace &lt;code&gt;\t&lt;/code&gt; with two blank spaces.&lt;/p&gt;

&lt;p&gt;Here it is in VSCode&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k8AWovGd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ra5scuz1g336gbz1rkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k8AWovGd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ra5scuz1g336gbz1rkn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Programmers These Days</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Sat, 08 Aug 2020 18:45:32 +0000</pubDate>
      <link>https://dev.to/vuetraining/programmers-these-days-e9j</link>
      <guid>https://dev.to/vuetraining/programmers-these-days-e9j</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jLy3f7gu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9jdnr9o4ztsocw331shu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jLy3f7gu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9jdnr9o4ztsocw331shu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Meme: Don't base your life around tech choices</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Fri, 07 Aug 2020 16:33:28 +0000</pubDate>
      <link>https://dev.to/vuetraining/meme-don-t-base-your-life-around-tech-choices-58km</link>
      <guid>https://dev.to/vuetraining/meme-don-t-base-your-life-around-tech-choices-58km</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wF-8KQL4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z67qgjswvotjtb56isq7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wF-8KQL4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z67qgjswvotjtb56isq7.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>VueJS Quick Tip: Access Vuex state from another module's actions</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Thu, 06 Aug 2020 18:33:56 +0000</pubDate>
      <link>https://dev.to/vuetraining/vuejs-quick-tip-access-vuex-state-from-another-module-s-actions-2ohg</link>
      <guid>https://dev.to/vuetraining/vuejs-quick-tip-access-vuex-state-from-another-module-s-actions-2ohg</guid>
      <description>&lt;p&gt;Working with Vuex modules and need access to another module's state?&lt;/p&gt;

&lt;p&gt;rootState has you covered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--70BiqI14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/we4g5gd57lccdbfhtgn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--70BiqI14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/we4g5gd57lccdbfhtgn9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Meme: Auto-import components with Nuxt 2.13+</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Wed, 05 Aug 2020 16:34:59 +0000</pubDate>
      <link>https://dev.to/vuetraining/meme-auto-import-components-with-nuxt-2-13-17fk</link>
      <guid>https://dev.to/vuetraining/meme-auto-import-components-with-nuxt-2-13-17fk</guid>
      <description>&lt;p&gt;With Nuxt 2.13 and above (or the @nuxt/components library), you can auto-import components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g6NtaqH0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p74c77rj1x3vxfq1h4zo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g6NtaqH0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p74c77rj1x3vxfq1h4zo.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>VueJS Quick Tip: Vue-router-next in the Composition API</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Tue, 04 Aug 2020 16:07:50 +0000</pubDate>
      <link>https://dev.to/vuetraining/vuejs-quick-tip-vue-router-next-in-the-composition-api-1i0l</link>
      <guid>https://dev.to/vuetraining/vuejs-quick-tip-vue-router-next-in-the-composition-api-1i0l</guid>
      <description>&lt;p&gt;The new version of Vue Router is almost ready.  Here's how to access the route and router within the Composition API's setup function.&lt;/p&gt;

&lt;p&gt;Make sure to call them before any await calls, or they might not work right!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--13AFeWjK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rtit99mlz4d7vc67vimp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--13AFeWjK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rtit99mlz4d7vc67vimp.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Vue Quick Tip: Router queryParams in reusable component</title>
      <dc:creator>VueTraining.net</dc:creator>
      <pubDate>Mon, 03 Aug 2020 16:15:26 +0000</pubDate>
      <link>https://dev.to/vuetraining/vue-quick-tip-router-queryparams-in-reusable-component-2b8e</link>
      <guid>https://dev.to/vuetraining/vue-quick-tip-router-queryparams-in-reusable-component-2b8e</guid>
      <description>&lt;p&gt;Change a Vue Router queryParam from within a reusable component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2BZCQqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wad1a1omfjssavaz0m3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2BZCQqA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wad1a1omfjssavaz0m3u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
