16
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Reactチュートリアルをやってみて分かったVue.jsとの違い

Posted at

背景

筆者は実務で約1年半Vue.jsの開発をしています。Reactは記事でも見ることが多く、SPAといえばReactが一番に出てくるけれど、Reactを一才触ったことがなかったです(結局リアクティブだからそんな違いはないだろうと思うのもあってあまり触っていなかった)。とはいえ、よく聞くReactを一切触っていないのも怖く、その勉強がてらチュートリアルをやってみました。以下の比較は主に、Vue.js options API と React Hook を比較しています。

筆者はReactについてほとんど知らないです。(クラスコンポーネントと関数コンポーネントの違いを最近知ったくらい)

Reactのチュートリアルが新しくなっていました。React hookを前提とした内容になっています。

チュートリアル:三目並べ – React

親コンポーネントのデータ書き換え

Vue.jsで親コンポーネントのデータを子コンポーネントから変更する際は emit を使用してデータを書き換えます。一方でReactでは、propでデータを書き換える無名関数(クロージャー)を渡すことでデータを書き換えます。Vue.jsでは、propで無名関数を渡すことは、コンポーネントの依存性が高まるため推奨されていません。

比較コード(親コンポーネントのcountを子コンポーネントから増加させる)
vue
const ParentComp = {
    template: `
      <child-comp
        :count="count"  
        @set-count="count + 1"  
      ></child-comp>
    `,
    data() {
      return {
        count: 0
      }
    },
  
    components: [ChildComp]
  }
  
  const ChildComp = {
    props: ["count"],
    emits: ["setCount"],
    template: `
      <button @click="$emit('setCount')">
              Clicked {{ count }} times
      </button>
    `
}
react
function ParentComp() {
    const [count, setCount] = useState(0);
  
    function handleClick() {
      setCount(count + 1);
    }
  
    return (
        <div>
          <ChildComp count={count} onClick={handleClick} />
        </div>
    );
  }
  
  function ChildComp({ count, onClick }) {
    return (
        <button onClick={onClick}>
          Clicked {count} times
        </button>
    );
  }

繰り返しの表示

Reactでは、JSXと言うマークアップ構文を使用することで簡単にテンプレートを変数に入れることができ、それを表示することができます。Vue.jsでは、template内でfor文を書いて実装します。React同じようにやろうと思えばできますが無駄な処理が多くなります。

比較コード(食べ物がリストで並んでいるコンポーネント)
vue
const ProductsComp = {
  template: `
    <ul>
      <li v-for="product in products" :key="product.id">
        {{ product.name }}
      </li>
    </ul>
  `,
  data() {
    return {
      products: [
        {id: 1, name: "apple"},
        {id: 2, name: "banana"}
      ]
    }
  },
}
react
function ProductsComp() {
  const products = [
    {id: 1, name: "apple"},
    {id: 2, name: "banana"}
  ]  
  const listItems = products.map(product =>
      <li key={product.id} >
        {product.name}
      </li>
  );
  return (
      <ul>{listItems}</ul>
  );
}

マークダウン構文

Vue.jsでは、bindを使用してtemplate内に表示したいマークアップを書きます。Reactでは、JSXと言うマークアップ構文を使用することで、関数コンポーネントがマークアップを返却することができ、より自由度が増しているように感じました。

比較コード(視聴済みか未視聴かで表示するテキストを切り替える)
vue
const TitleComp = {
  template: `
    <template v-if="isWatched">
      <p>watched</p>
    </template>
    <template v-else>
      <p>unwatch</p>
    </template>
  `,
  data() {
    return {
      isWatched: false
    }
  }
}
react
function TitleComp() {
  const [isWatched, toWatched] = useState(false);

  if (isWatched) {
    return (
        <p>watched</p>
    )
  } else {
    return (
        <p>unwatch</p>
    )
  }
}

やってみた感想

Vue.jsをある程度やっていると、参入障壁は非常に低いと思いました。コンポーネント間のデータのやり取りの考えがわかっていると特に困ることはないと思います。

チュートリアルの内容とは関係ないのですが、ページの表示が早く感じました。Next.jsを使用しているので、SSG機能を使用しているかな?Next.jsを書いたことがないので今後やってみたい。

Qiitaの折りたたみが書きずらすぎた。

16
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?