<?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: Paul Shen</title>
    <description>The latest articles on DEV Community by Paul Shen (@paulshen).</description>
    <link>https://dev.to/paulshen</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%2F341299%2Fee343be3-11b3-43c1-a203-c65bf2d9b81f.jpeg</url>
      <title>DEV Community: Paul Shen</title>
      <link>https://dev.to/paulshen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/paulshen"/>
    <language>en</language>
    <item>
      <title>Comparing Vue and React</title>
      <dc:creator>Paul Shen</dc:creator>
      <pubDate>Mon, 10 Aug 2020 15:54:10 +0000</pubDate>
      <link>https://dev.to/paulshen/comparing-vue-and-react-20b4</link>
      <guid>https://dev.to/paulshen/comparing-vue-and-react-20b4</guid>
      <description>&lt;p&gt;As a React developer, I wanted to dive into Vue to learn how it approached building JavaScript UI. How do they differ? Is one better?&lt;/p&gt;

&lt;p&gt;I'm using Vue 2 but have also spent some time looking at &lt;a href="https://v3.vuejs.org/"&gt;Vue 3&lt;/a&gt;. Please call me out on any inaccuracies 🙃&lt;/p&gt;

&lt;p&gt;Let's start by looking at their taglines. React is "a declarative, efficient, and flexible JavaScript library for building user interfaces." Vue is "a progressive, incrementally-adoptable JavaScript framework for building UI on the web."&lt;/p&gt;

&lt;p&gt;Very similar sentences with a few important differences. Just like the libraries themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;At a high level, the frameworks take similar approaches to the same goal.&lt;/li&gt;
&lt;li&gt;React is JavaScript-centric vs Vue uses hybrid HTML template/JS.&lt;/li&gt;
&lt;li&gt;React uses a push update model vs Vue implements reactivity via observing.&lt;/li&gt;
&lt;li&gt;Vue has more built-in. React is more barebones and relies on community.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Language approach
&lt;/h2&gt;

&lt;p&gt;Let's jump right in and look at a pretty full-featured component. I'm going with the Vue 3 &lt;a href="https://v3.vuejs.org/guide/composition-api-introduction.html"&gt;composition API&lt;/a&gt; because it seems like the direction Vue is heading. There are obvious parallels: the Vue component options API is to React class components as Vue 3 composition API is to React hooks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// UserProfile.vue&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&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;div&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="nc"&gt;Avatar&lt;/span&gt; &lt;span class="na"&gt;v&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"showAvatar"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"id"&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="nc"&gt;UserBody&lt;/span&gt; &lt;span class="na"&gt;v&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user"&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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"$emit('follow-click')"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Follow&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;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;showAvatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toRefs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;user&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;data&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="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateUser&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;user&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;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// React&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;showAvatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onFollowClick&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;showAvatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;onFollowClick&lt;/span&gt;&lt;span class="p"&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="k"&gt;void&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&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="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useEffect&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;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setUser&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="nx"&gt;id&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;div&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showAvatar&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Avatar&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&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;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserBody&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&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;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;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="nx"&gt;onFollowClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Follow&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;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&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;I used to be quite allergic to HTML templates (e.g. mustache) because of their loose run-time nature. Back in the day, it was a bunch of string manipulation. However, in Vue (and Svelte and other modern frameworks), templates are processed at build-time into JavaScript. You can use &lt;a href="https://vue-next-template-explorer.netlify.app/"&gt;Vue Template Explorer&lt;/a&gt; to see how Vue templates transpile to JavaScript.&lt;/p&gt;

&lt;p&gt;React's JSX is just sugar for JavaScript.&lt;/p&gt;

&lt;p&gt;In a way, you could also say that Vue's templates are also JavaScript sugar. However, the transform is more involved and Vue-specific.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;p&gt;One advantage of Vue's template syntax is that because it is more restrictive, the compiler is able to perform more optimizations, such as separating out static template content to avoid rerenders. React can do something similar with a &lt;a href="https://babeljs.io/docs/en/babel-plugin-transform-react-constant-elements"&gt;Babel plugin&lt;/a&gt; but this is not common. Theoretically, I believe Vue could make more optimizations from template syntax.&lt;/p&gt;

&lt;p&gt;A disadvantage with Vue templates is that there are times when JavaScript's expressiveness is &lt;a href="https://v3.vuejs.org/guide/render-function.html#render-functions"&gt;sorely missed&lt;/a&gt; or even necessary. In those cases, Vue recommends using a &lt;code&gt;render&lt;/code&gt; function, either via the more verbose &lt;code&gt;createElement&lt;/code&gt; or JSX. An example I ran into is wanting a local variable inside a template loop. Translating between Vue template and JSX is a manual process. I think you probably need to be familiar with both template and JSX to be a Vue developer, in which case React's one approach seems better.&lt;/p&gt;

&lt;p&gt;If you use React hooks, React components are just functions. All the logic lives inside this function. Vue separates the component definition from the template (or &lt;a href="https://v3.vuejs.org/guide/render-function.html"&gt;render function&lt;/a&gt;). Using the new Composition API above, the component definition is inside one &lt;code&gt;setup&lt;/code&gt; function. This is a notable difference; &lt;strong&gt;React hooks are run on every render but &lt;code&gt;setup&lt;/code&gt; is only run once on initialization&lt;/strong&gt;. Vue sets up listeners (lifecycle and reactive values) whereas React specifies effects on each render.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Handling
&lt;/h3&gt;

&lt;p&gt;Event handling is another example of the differing language approach. React has no special syntax; it's just JavaScript functions. Vue provides syntax for listening to and emitting events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MyVueComponent&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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"$emit('increment')"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Increment&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;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyVueComponent&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"methodName"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// MyReactComponent&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="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onIncrement&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Increment&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;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyReactComponent&lt;/span&gt; &lt;span class="na"&gt;onIncrement&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;jsFunction&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;You can see here the differing approaches to events. React passes a JavaScript function to the component. Vue components emit events, which are identified as strings with associated data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Static analysis
&lt;/h3&gt;

&lt;p&gt;At a high level, React is better suited for static analysis, such as TypeScript. Its JavaScript-centric approach puts it closer to the language so most editor/tooling just works. I set up VSCode with Vetur (Vue's recommended tooling) and didn't get semantic langauge features (e.g. checking, autocomplete, go to definition) inside the Vue template. Note: I found Vetur has an experimental setting for "Template Interpolation Service" which adds a lot of these features but it still misses features like find references.&lt;/p&gt;

&lt;p&gt;Some Vue features like named slots, events, and their props (React children equivalent) are too dynamic for full static analysis. For example, components can emit custom events but there isn't an obvious way to write out that contract.&lt;/p&gt;

&lt;p&gt;Vue provides a global namespace although it is not always recommended. For example, you can register components by name to the global namespace. &lt;a href="https://v3.vuejs.org/guide/plugins.html"&gt;Vue plugins&lt;/a&gt; can inject global methods, properties, and mixins. Global namespaces, while convenient at times, play less nicely with tooling and scalable codebases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update model
&lt;/h2&gt;

&lt;p&gt;The biggest functional difference between Vue and React is how they handle updates. Vue uses observables (via JavaScript &lt;code&gt;Proxies&lt;/code&gt; or &lt;code&gt;defineProperty&lt;/code&gt;) to implement reactivity. In short, it modifies data to track when properties are read or written. This allows for fine-grained dependency tracking; Vue knows which properties have been read so it can rerender and update views only when those properties change. This is smarter than a stock &lt;code&gt;React.memo&lt;/code&gt;, which compares equality for all props.&lt;/p&gt;

&lt;p&gt;In comparison, React uses a push update model. Rerenders are triggered by a function call somewhere (state update or reducer dispatch). When a React component updates, it will rerender all its children as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MyVueComponent&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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"count += 1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&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="si"&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="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&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="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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyReactComponent&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="nx"&gt;React&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="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;&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="nx"&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;=&amp;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;&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;&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The way I think of Vue's update model is as if all components were wrapped in &lt;code&gt;React.memo&lt;/code&gt; and the equality function was a dynamic one that compared only props/state that were used on the last render.&lt;/p&gt;

&lt;p&gt;Vue's update model is a lot like &lt;a href="https://mobx.js.org/"&gt;MobX&lt;/a&gt;. Your atoms are your props/data and you can also have computed properties. Note: Vue currently rerenders whenever data underlying a computed property changes, even if the computed property itself does not change. This feature would be really nice as this is hard to express in React using &lt;code&gt;React.useMemo&lt;/code&gt; without creating a wrapper component.&lt;/p&gt;

&lt;p&gt;Out-of-the-box, Vue performs more granular updates so Vue updates are more performant by default. Of course, React has &lt;code&gt;React.memo&lt;/code&gt; but that requires understanding of closures and when to use &lt;code&gt;React.useMemo&lt;/code&gt; and &lt;code&gt;React.useCallback&lt;/code&gt;. Vue isn't off the hook though. Reactivity via injecting observables comes with &lt;a href="https://v3.vuejs.org/guide/reactivity-fundamentals.html#destructuring-reactive-state"&gt;its&lt;/a&gt; &lt;a href="https://v3.vuejs.org/guide/composition-api-introduction.html#reactive-variables-with-ref"&gt;gotchas&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  API surface area
&lt;/h2&gt;

&lt;p&gt;It's hard for me to be objective because I have a lot more familiarity with the React API. However, I still feel that React has a smaller API and fewer React-specific concepts to learn (ignoring concurrent mode and time-slicing).&lt;/p&gt;

&lt;p&gt;A number of things are more convenient in Vue. Here are a few examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  v-model
&lt;/h3&gt;

&lt;p&gt;Vue has sugar for two-way data binding. It's quite nice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MyVueComponent&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&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;v&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"message"&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;message&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;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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;message&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The following is quoted from the &lt;a href="https://reactjs.org/docs/two-way-binding-helpers.html"&gt;React docs&lt;/a&gt;: In React, data flows one way: from owner to child. We think that this makes your app’s code easier to understand. You can think of it as “one-way data binding.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyReactComponent&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;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&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="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;div&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;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;message&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="nx"&gt;setMessage&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="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;} /&amp;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;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&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;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;div&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;h3&gt;
  
  
  Combining class names
&lt;/h3&gt;

&lt;p&gt;Vue has special &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;style&lt;/code&gt; handling. These properties get merged and also handle object maps and arrays.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MyVueComponent&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"my-class-name"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&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="nc"&gt;MyVueComponent&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{ active: isActive }"&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;This is more tedious with React. There is nothing special about &lt;code&gt;className&lt;/code&gt;. Most people use a third-party library (like &lt;code&gt;classnames&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyReactComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;className&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-class-name &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyReactComponent&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&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;h3&gt;
  
  
  Reactivity
&lt;/h3&gt;

&lt;p&gt;I will add a mention here for Vue's reactivity. I found it magical but pleasant to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"count += 1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&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="si"&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="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// This causes rerender&lt;/span&gt;
    &lt;span class="k"&gt;this&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;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;The fact that mutating what looks like a local variable causes a rerender is still a little beyond my comfort zone 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue as a framework
&lt;/h2&gt;

&lt;p&gt;React pitches itself as a &lt;strong&gt;library&lt;/strong&gt; and Vue as a &lt;strong&gt;framework&lt;/strong&gt;. The line is blurry but Vue does more out-of-the-box than React. Vue has transitions and animations built-in. It has blessed libraries for routing and state management (vuex).&lt;/p&gt;

&lt;p&gt;React, as in the core React, focuses on only the rendering layer. The other pieces are provided by the ecosystem, which fortunately, is very vibrant.&lt;/p&gt;

&lt;p&gt;With my limited experience, bootstrapping an app feels about the same both with &lt;code&gt;vue-cli&lt;/code&gt; and &lt;code&gt;create-react-app&lt;/code&gt;. I like Vue &lt;a href="https://vuejs.org/v2/guide/single-file-components.html"&gt;Single File Components&lt;/a&gt;, which allows you to define component-scoped CSS in the same file as the template and component logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not too different
&lt;/h2&gt;

&lt;p&gt;While I've been spending time on the differences, they have many similarities. They are both web UI view libraries and a lot of the concepts map from one to the other.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both use virtual DOM and support JSX&lt;/li&gt;
&lt;li&gt;Vue slots and React children&lt;/li&gt;
&lt;li&gt;Vue props/data and React props/state&lt;/li&gt;
&lt;li&gt;Vue teleport and React portal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which one should you use?
&lt;/h2&gt;

&lt;p&gt;You probably expected this coming but I'm not going to give you a definite answer. It depends! You can be successful and productive with either one.&lt;/p&gt;

&lt;p&gt;If you are a stickler for correctness and love type systems (which I am one), you will probably prefer React. It works better with TypeScript and has a purer language approach. Vue has a global namespace (although you can mostly avoid it) but features like custom events, plugins, and mixins embrace the dynamic nature of JS. For this reason, I would favor React in complex apps in large codebases with many engineers.&lt;/p&gt;

&lt;p&gt;If you like the idea of starting with HTML/static content and sprinkling on JavaScript, then you might like Vue's template approach. Many websites really are of this nature, static content with some interactivity.&lt;/p&gt;

&lt;p&gt;For developers less familiar with JavaScript, Vue is probably easier to get started with. Templates are intuitive and are incrementally adoptable. You don't need to think about rerendering and data-binding is easy to understand. This isn't to say that you can't build complex apps with Vue. If you spend a lot of time with JavaScript, you might like React's more pure language approach.&lt;/p&gt;

&lt;p&gt;Finally, it's hard to ignore React's mass adoption and large ecosystem. For companies, React would be the less risky choice. More engineers have React experience than Vue experience; hiring will likely be easier. Also, there are more alternative React render targets, like React Native, that you may find useful.&lt;/p&gt;

&lt;p&gt;At the end of the day, you can be productive with both frameworks. I personally still prefer React but I can't say it's strictly better.&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>VSCode with Vim tips</title>
      <dc:creator>Paul Shen</dc:creator>
      <pubDate>Sun, 28 Jun 2020 17:20:15 +0000</pubDate>
      <link>https://dev.to/paulshen/vscode-with-vim-tips-p39</link>
      <guid>https://dev.to/paulshen/vscode-with-vim-tips-p39</guid>
      <description>&lt;p&gt;My go-to editor of choice today is VSCode with the &lt;a href="https://marketplace.visualstudio.com/items?itemName=vscodevim.vim"&gt;VSCodeVim extension&lt;/a&gt;. I won't go into why VSCode and Vim are great 😄. Instead, here are some tips for Vim users in VSCode.&lt;/p&gt;

&lt;p&gt;VSCodeVim is a community VSCode plugin that adds good (though not perfect) Vim emulation. It also includes a few popular Vim plugin features. Overall, I'm quite happy with this combination. My main gripes are with performance and responsiveness (compared to Vim) but the extra VSCode features are well worth it for me.&lt;/p&gt;

&lt;p&gt;It's worth scrolling through the VSCodeVim &lt;a href="https://github.com/VSCodeVim/Vim/blob/master/README.md"&gt;README&lt;/a&gt;, which is packed with features. Here are some of my favorites.&lt;/p&gt;

&lt;h2&gt;
  
  
  VSCodeVim Tricks
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/VSCodeVim/Vim#-vscodevim-tricks"&gt;VSCodeVim tricks&lt;/a&gt; section includes &lt;code&gt;g d&lt;/code&gt; (go-to definition) and &lt;code&gt;g h&lt;/code&gt; (show hover tooltip). Note that you can often mix-and-match VSCode shortcuts. For example, I use &lt;code&gt;⌘ + d&lt;/code&gt; (VSCode shortcut to add next search selection) instead of VSCodeVim's &lt;code&gt;g b&lt;/code&gt;. I usually follow multiple selections with &lt;code&gt;c&lt;/code&gt; to change the selections.&lt;/p&gt;

&lt;p&gt;Many of VSCode features are built for mouse navigation. Some of these includes &lt;code&gt;⌘ + click&lt;/code&gt;, &lt;code&gt;⌥ + ⌘ + click&lt;/code&gt;, etc. With Vim, we want to stay on the keyboard as much as possible. I recommend browsing the &lt;a href="https://code.visualstudio.com/docs/getstarted/keybindings#_keyboard-shortcuts-editor"&gt;keyboard shortcuts editor&lt;/a&gt; and adding your own keymaps. One of my favorite commands is &lt;code&gt;editor.action.revealDefinitionAside&lt;/code&gt;, which opens the definition of the current symbol under your cursor in a split. I map this to &lt;code&gt;g D&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vim.normalModeKeyBindings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"g"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"D"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"commands"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"editor.action.revealDefinitionAside"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Easymotion
&lt;/h2&gt;

&lt;p&gt;VSCodeVim comes with built-in &lt;a href="https://github.com/VSCodeVim/Vim#vim-easymotion"&gt;easymotion&lt;/a&gt;! If you're not familiar with the Vim &lt;a href="https://github.com/easymotion/vim-easymotion"&gt;plugin&lt;/a&gt;, easymotion shows markers for Vim motions, allowing you to jump to a target. The ones I use are search by two characters and start of line forwards and backwards. To turn on this plugin, set the VSCode setting &lt;code&gt;"vim.easymotion": true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I use easymotion A LOT, pretty much for any motion that isn't on the same line. I map &lt;code&gt;s&lt;/code&gt; to easymotion 2 char and &lt;code&gt;⌃ + j&lt;/code&gt; &lt;code&gt;⌃ + k&lt;/code&gt; to easymotion line forwards backwards, respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"vim.normalModeKeyBindingsNonRecursive"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"s"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"after"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;leader&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;leader&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;C-j&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"after"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;leader&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;leader&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"j"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"before"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;C-k&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"after"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;leader&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;leader&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"k"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Semantic selections
&lt;/h2&gt;

&lt;p&gt;Did you know that VSCode has &lt;a href="https://code.visualstudio.com/docs/editor/codebasics#_shrinkexpand-selection"&gt;semantic selections&lt;/a&gt;? You can expand and shrink your text selection powered by the language service (e.g. TypeScript). It almost works with VSCodeVim with the caveat that you need to press &lt;code&gt;v&lt;/code&gt; before inputting your action, even though it already looks like a visual selection.&lt;/p&gt;

&lt;p&gt;It's worth noting VSCodeVim has its own expand motion &lt;code&gt;a f&lt;/code&gt; but it is not semantic. However, it does the right thing 90% of the time and may be worth using as your default because of the tighter integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Surround
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/VSCodeVim/Vim#vim-surround"&gt;vim-surround&lt;/a&gt; emulation is worth a mention. It provides operations to work with surrounding characters like parentheses, braces, quotes, etc. If you are working on web frontend, it makes it easy to wrap things with XML tags.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;S [desired char]&lt;/code&gt; will wrap your visual selection. A common operation I perform is select a chunk of text in visual mode and then type &lt;code&gt;S &amp;lt;div&amp;gt;&lt;/code&gt; to wrap it in a div tag (obviously replace with tag of choice). You can even type attributes &lt;code&gt;S &amp;lt;div className="foo"&amp;gt;&lt;/code&gt; but the input is hidden until you close the tag. Similarly, wrap with &lt;code&gt;S {&lt;/code&gt; &lt;code&gt;S (&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;Editor tips are never comprehensive but I hope you found something to add to your toolkit. &lt;a href="https://twitter.com/_paulshen"&gt;Tell me&lt;/a&gt; your favorites!&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>vim</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Will this work in React Concurrent mode?</title>
      <dc:creator>Paul Shen</dc:creator>
      <pubDate>Tue, 25 Feb 2020 02:25:43 +0000</pubDate>
      <link>https://dev.to/paulshen/will-this-work-in-react-concurrent-mode-43d0</link>
      <guid>https://dev.to/paulshen/will-this-work-in-react-concurrent-mode-43d0</guid>
      <description>&lt;p&gt;&lt;a href="https://reactjs.org/docs/concurrent-mode-intro.html"&gt;React Concurrent&lt;/a&gt; is the exciting next big thing for React. It touts performance benefits and ergonomic ways to implement &lt;a href="https://reactjs.org/docs/concurrent-mode-suspense.html#approach-3-render-as-you-fetch-using-suspense"&gt;render-as-you-fetch&lt;/a&gt; applications.&lt;/p&gt;

&lt;p&gt;Opting into concurrent mode forces developers to think about React differently than they might have. Existing code that worked fine in today’s React may not work in Concurrent mode.&lt;/p&gt;

&lt;p&gt;While React Concurrent mode is not ready for primetime, we have enough information to prepare and make sure our code and patterns support it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A component’s render is no longer coupled with a host (DOM) update.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the biggest change to understand to make sure our components work with Concurrent mode. We need to make sure our render functions do not have side effects. This includes operations like updating refs, adding event listeners, and logging.&lt;/p&gt;

&lt;p&gt;A render call does not mean that the result will be output to the DOM. The update may not show up for a period of time (could be arbitrarily long) or even ever. We'll see below how this is possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactive, the customer support team
&lt;/h2&gt;

&lt;p&gt;To illustrate this, we'll use &lt;em&gt;Reactive&lt;/em&gt;, a fictional customer support team that uses a React-like API for handling support tickets.&lt;/p&gt;

&lt;p&gt;When the Reactive team is ready for more tickets, they call your render function to add your ticket to the queue. When your ticket is resolved, you want to tweet and thank the team.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MySupportTicket&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// INCORRECT&lt;/span&gt;
  &lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My address is changed! Thanks!&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Ticket&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;changeAddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Venice, CA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Most of the time, Reactive is very responsive and processes your ticket immediately. In React, this is equivalent to updating the DOM immediately after render is called. Prior to Concurrent mode, this was how React always worked.&lt;/p&gt;

&lt;p&gt;When Reactive got upgraded with concurrent powers, it gained more liberty with when to process support tickets. Reactive may hold off on processing your ticket because there are more urgent tickets to handle. There's no guarantee as to when your ticket will get processed. This is why we need to move the &lt;code&gt;API.tweet&lt;/code&gt; call into an effect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MySupportTicket&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&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;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tweet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My address is changed! Thanks!&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Ticket&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;changeAddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Los Angeles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;React with Concurrent mode is similar. React can pause work to handle more important updates first. It can also pause work because a component is &lt;a href="https://reactjs.org/docs/concurrent-mode-suspense.html"&gt;suspending&lt;/a&gt;. This is why it's important to make sure your effects are called from &lt;code&gt;useEffect&lt;/code&gt; or &lt;code&gt;useLayoutEffect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is a &lt;a href="https://codesandbox.io/s/quirky-pascal-fvv96?expanddevtools=1&amp;amp;fontsize=14&amp;amp;hidenavigation=1&amp;amp;theme=dark"&gt;CodeSandbox example&lt;/a&gt; of a delayed update. Notice how we're thanking Reactive (see console) before they resolve the ticket. Uh oh.&lt;/p&gt;

&lt;p&gt;In fact, Reactive may never process your submitted ticket. Why would they do such a thing?!&lt;/p&gt;

&lt;h2&gt;
  
  
  Rendered components may never mount
&lt;/h2&gt;

&lt;p&gt;While you are waiting for your ticket to be resolved, you decide to cancel your ticket. The ticket is no longer needed. In React, this is possible when a new update no longer renders your component. &lt;strong&gt;A component that is rendered may never show up on the screen!&lt;/strong&gt; This is why it's dangerous to have side effects in a class component's constructor or render. React may throw away the component and you're left with phantom subscriptions.&lt;/p&gt;

&lt;p&gt;Here is a &lt;a href="https://codesandbox.io/s/awesome-agnesi-hvdjt?expanddevtools=1&amp;amp;fontsize=14&amp;amp;hidenavigation=1&amp;amp;theme=dark"&gt;CodeSandbox example&lt;/a&gt; where a rendered component is never shown in the DOM. Notice that &lt;code&gt;&amp;lt;MySupportTicket&amp;gt;&lt;/code&gt; never shows up on the screen even though it is rendered.&lt;/p&gt;

&lt;h2&gt;
  
  
  A value logger
&lt;/h2&gt;

&lt;p&gt;Let's put these principles into practice. We want to build a component that console.logs the most recently rendered prop once a second.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// INCORRECT&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ValueLogger&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// We use a ref here so we can modify the value inside the interval closure&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&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="nx"&gt;lastValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setInterval&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1000&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;gt;&lt;/span&gt; &lt;span class="nx"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&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="k"&gt;return&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Can you identify the incorrect line?&lt;/p&gt;

&lt;p&gt;With Concurrent mode, we can't have side effects in render. They need to be run from &lt;code&gt;useEffect&lt;/code&gt; or &lt;code&gt;useLayoutEffect&lt;/code&gt;. This includes updating refs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ValueLogger&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&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="nx"&gt;useEffect&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="c1"&gt;// React will run this after the DOM shows this update.&lt;/span&gt;
    &lt;span class="nx"&gt;lastValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setInterval&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1000&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;gt;&lt;/span&gt; &lt;span class="nx"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&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="k"&gt;return&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Without this fix, we may log a value that was never rendered. Using React's &lt;a href="https://reactjs.org/docs/concurrent-mode-intro.html#blocking-vs-interruptible-rendering"&gt;git analogy&lt;/a&gt;, the component could have been rendered on a branch and was not ready for master.&lt;/p&gt;

&lt;p&gt;Hopefully, the customer support analogy helps illustrate how React may decide to delay or throw away render updates. This analogy doesn't hold up all the way. React is not as fickle as a customer support team. Its behavior is predictable. It is just open source code after all.&lt;/p&gt;

&lt;p&gt;By guaranteeing render does not have side effects, React gains the power of concurrent mode.&lt;/p&gt;

</description>
      <category>react</category>
    </item>
  </channel>
</rss>
