7839

雑草魂エンジニアブログ

Vue.jsエンジニアのReact入門 - コンポーネントの実装方法

Vue.js エンジニアの React 入門。
React の実装方法を Vue.js と対比しながら理解を深めていくシリーズ。

今回は、「コンポーネントの実装方法」を紹介する。

Vue.js は HTML テンプレートであり、React は JSX で全く異なる。(ただし、React は必ず JSX でないといけないかというと、全くそういうことはない。反対に、Vue.js を JSX で記述することも可能である。React の場合は、 JSX で書くと、記述量が少なくなり、効率的に開発できるビルド環境を整えてくれているので、JSX で記述することが通例となっている。)

Vue.js の場合

Vue.js は HTML テンプレートを用いる。ファイルの拡張子は、 .vueであり、HTMLを記述する <template> ブロック、CSSを記述する style ブロック、JavaScriptを記述する <script> ブロックの3つに分かれている。

<template>
  <div class="app">
    <h1>Hello World</h1>
    <p>This is test.</p>
  </div>
</template>
<script>
export default {
  data: () => ({}),
  computed: {},
  methods: {}
}
</script>
<style scoped>
.app {
  background: black;
  padding: 10px;
}
</style>

React の場合

React は、JSX を用いる。ファイルの拡張子は、 .jsxとなる。そして、コンポーネントに2つの種類がある。

  1. 関数型
  2. クラス型

関数型

まずは、一番シンプルな関数型です。

import React from "react"

const App = (props) => {
  return (
    <div className="app">
      <h1>Hello World, {props.name}</h1>
      <p>This is test.</p>
    </div>
  )
}

export default App

これは、データの入った propsというオブジェクトを引数として受け取り、React 要素を返す関数である。これは文字通り JavaScript の関数なので、このようなコンポーネント関数コンポーネント (function component) と呼ぶ。React 要素は一見、普通の HTML を返却しているようにみえるが、これは JSX という拡張構文である。クラス名の命名も、 class ではなく、 classNameとなっていることがわかるかと思う。

クラス型

コンポーネントを定義するために ES6 クラス を使用する。

import React from "react"

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = { name: "太郎" }
  }

  componentDidMount() {
  }

  componentWillUnmount() {
  }

  render() {
    return (
      <div className="app">
        <h1>Hello World, {this.props.name}</h1>
        <p>This is test.</p>
      </div>
    )
  }
}

export default App

React.Component を継承した App コンポーネントを定義し、 render メソッドを用いて React要素を返却している。クラス型の場合は、ローカル state やライフサイクルメソッド(componentDidMountやcomponentWillUnmountなど)が使える。Vue.js で考えると、コンポーネント内の変数として data メソッドで管理していたものが、React のローカル state であり、ライフサイクルメソッドは、mountedやbeforeDestroyなど Vue.js にも同じようなライフサイクルがあるので、わかりやすいように思われる。

上記だけで考えると、クラスコンポーネントの方がいいんじゃないかと思われる。

しかしながら、Ver.16.8 で関数コンポーネントのための フック (hook) という新機能 が追加された。これがかなり強力で、関数コンポーネントでも useStateuseRender を使うことで、状態管理を行うことができるようになり、 useEffect を使うことでライフサイクルメソッドが使えるようになったのである。また、フックの詳細は別の記事で紹介するが、この Ver.16.8 のアップデートは、React 界隈に大きな変化を与えた。

詳細が気になる方はこちらから、どうぞ。

ja.reactjs.org

React 開発チームは、クラスコンポーネントでの複雑性(Thisの問題等)を指摘しており、関数コンポーネントをメインに使ってほしいと思っているようだ。なので、JavaScript もしっかり理解する上では、クラスコンポーネントを使ってもいいが、これから React で簡潔なコードを書く場合は、フックを導入しての関数コンポーネントで設計するのが有用的と思われる。

一部ではあるが、各種メソッドの比較を以下に示す。

Vue.js React
DOMの複製 v-for map等
DOMの条件分岐 v-if / v-show JSX内でなし
論理 && 演算子 / 三項演算子
(renderするReactコンポーネントを切り替える)
要素をWrapする要素 <template> <React.Fragment>
cssクラス v-bind className(動的変数不可)
classnames ライブラリを使う
HTML変数 v-html dangerouslySetInnerHTML
ベントハンドリング v-on / @click等 onClick
キャメルケース指定
ローカル変数 data: () => ({}) useSate
双方バインディング v-model 自動的にバインディングしてくれない
useStateで実装する
DOM要素へのアクセス this.$refs useRef
算出プロパティ computed 関数を自作
useMemo
監視プロパティ watch なし

詳細に関しては、今後の記事で実装しながら、紹介していく。

まとめ

今回は、コンポーネントの実装に焦点をあてて、Vue.js と React の違いをみてきた。対比することで、挙動がイメージできるため、React を理解しやすいように思えた。

それでは、ステキな開発ライフを。