オンプレ系インフラエンジニアがAzureを勉強する

いつか誰かの何かの役に立つと嬉しいな

【JavaScript】サンプルボタン作成 - その4(React利用 - クラスコンポーネントver.)

はじめに

JavaScriptを勉強し始めました。
Reactのありがたみを知るために、簡単なサンプルボタンを下記パターンで書いて比較してみます。
それぞれの書き方の差を確認するために書いたので、実装としては良い書き方じゃないところもあります。

題材

下記のようなボタンをサンプルにします。
【要件】
OKボタンをクリックするとNGボタンに変わる
OKボタン、NGボタンともにマウスオーバーで色が変わる
ボタンにカーソルを合わせるとマウスカーソルが変化する
f:id:mitsunooon:20201020222502g:plain
 

共通部分(CSS)

CSSは一律共通にしています。

/* ボタンの基本にするスタイル */
/* OKの時 */
.sampleButton-ok {
    width: 128px;
    height: 40px;
    margin: 8px;
    background-color: #ff3535;
    border: solid 1px #ff3535;
    border-radius: 4px;
    color: #fff;
    font-size:12px;
    line-height: 40px;
    text-align: center;
    cursor: pointer;
}

/* OKの時のマウスオーバー */
.sampleButton-ok:hover {
    background-color: #da3232;
}

/* NGの時の基本スタイル(※OKボタンからの差分のみ) */
.sampleButton-ng {
    background-color: #fff;
    border: solid 1px #3553ff;
    color: #3553ff;
}

/* NGの時のマウスオーバー */
.sampleButton-ng:hover{
    background-color: #eee;
}

 

HTML/CSS/JavaScript-React利用有り-クラスコンポーネント使用ver.

HTML/CSS/JavaScriptに加えてReactを使います。
Reactのコンポーネントにも関数コンポーネントとクラスコンポーネントがあるので、今回はクラスコンポーネントを使います。
ja.reactjs.org

プロジェクトの作成

Reactのプロジェクトを作成するところは備忘録として記載します。
Reactを使うための初期構築についてはいろいろわかりやすい記事があるのでそちらをご覧ください。
[手順]

  • Visual Studio Codeを開く。
  • 新しいターミナルを開く。
  • npx create-react-app [プロジェクト名]でプロジェクトを新規作成。
  • cdでプロジェクトのディレクトリに移動。
  • yarn startで実行。

不要なファイルもたくさんあるため、必要に応じて削除します。

index.html

タイトルの部分だけ変更します。
不要な部分も削除します。(残しておいてもボタンの挙動には影響ないです。)

index.js

App.jsというメインになるページを呼び出しています。
ここで直接ボタンのコンポーネントを呼ぶこともできますが、複雑なUIを作っていくことを考えると、ここでボタンのような一機能のコンポーネントを直接呼び出すことはあんまりないかなと思います。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

App.js

ここでSampleButtonというボタンのコンポーネントを呼び出します。
クラスを適用するためのidの指定をしておきます。

import React from 'react';
import SampleButton from './SampleButton';

function App() {
  return (
    <div >
      <SampleButton id="samplebutton"/>
    </div>
  );
}

export default App;//他の関数から呼び出せるように

SampleButton.js

ボタンの本体部分になります。
ここからが関数コンポーネントと異なる部分になります。

import './SampleButton.css';
import React from 'react';

class SampleButton extends React.Component {
  // コンストラクター
  constructor(props) {
    super(props);
    // テキストの初期値設定
    this.state = {
      text: 'OK',
    };
  }

  // クリックイベントで実行する処理
  handleClick() {
    const samplebutton = document.getElementById(this.props.id);

    if (!samplebutton.classList.contains('sampleButton-ng')) {
      // テキストの変更
      this.setState(state => ({
        text: 'NG'
      }));
      // クラスの追加
      samplebutton.classList.add('sampleButton-ng');
    } else {
      // テキストの変更
      this.setState(state => ({
        text: 'OK'
      }));
      // クラスの追加
      samplebutton.classList.remove('sampleButton-ng');
    }
  }

  render() {
    // ボタンを複数個使用する場合はidで判別するため、決め打ちではなく上位から受け取ったもの指定にする
    return (
      <div onClick={this.handleClick.bind(this)} className="sampleButton-ok" id={this.props.id}>
        {this.state.text}
      </div >
    )
  }
}

export default SampleButton;

ボタンを増やす場合

コンポーネント呼び出し時のidを分けるだけで同じボタンが量産できます。

App.js

import React from 'react';
import SampleButton from './SampleButton';

function App() {
  return (
    <div>
      <SampleButton id="samplebutton1"/>
      <SampleButton id="samplebutton2"/>
      <SampleButton id="samplebutton3"/>
    </div>
  );
}

export default App;//他の関数から呼び出せるように

SampleButton.js
変更なし。

コード全体

 コード全体は下記Githubにあげています。
github.com

おわりに

以上4パターンで書き比べてみました。
ここまでやってようやくReactのありがたみが少しわかったような気がします。
まだそれぞれの特性や細かい意味とかまでは使いこなせていないのでもっと精進します。
 stateとかhookとか値の保持が必要になってくるとまた複雑になってくると思うので、そのあたりもちゃんと書き分けを整理したいと思います。
JavaScriptとTypeScriptの書き方比較もやりたいです。