クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【React】クラスを使ったコンポーネントの書き方(React.Component、render()、super())

Reactの続きです。前回はコンポーネントでstyle属性や四則演算を設定しました。今回はクラスを使ってみます。Reactのコンポーネントでのクラスは、親クラスReact.Componentの継承、必須であるrender()メソッド、コンストラクタのsuper()、などの書き方がありました。それでは行きましょう!

【目次】

※参考:【React】コンポーネントの属性値を読み込む(style、テキスト、四則演算) - クモのようにコツコツと

※Reactでやってみたことまとめ
qiita.com

クラスとは

今回も掌田さんの「React.js & Next.js入門」を参考に進める。

React.js & Next.js超入門

React.js & Next.js超入門

コンポーネントらしいコンポーネントを作るには「クラス」へのステップアップが必要とのこと。

クラスについては以前のJS記事でも書いている。

※参考:【JS】newとプロトタイプとクラス - クモのようにコツコツと

※参考:【JS】アロー関数のthisの挙動(プロトタイプとクラスの違い) - クモのようにコツコツと

こんな書き方

class クラス名 {
  // コンストラクタ
   constructor(引数) {
    this.プロパティ = 値;
  }
  // メソッド 
  メソッド() {
    // コンストラクタ(this.プロパティ)を使った処理
  }
}

// インスタンス生成
let オブジェクト = new クラス(引数);
 
// 実行(引数が使われる)
オブジェクト.メソッド();
  • class宣言でクラスを作る
  • constructor()メソッドの中でコンストラクタ(this.プロパティ)を設定
  • コンストラクタを使ったメソッドを定義
  • オブジェクトにnewでクラスのインスタンスを生成
  • オブジェクトでメソッドを実行(オブジェクトに設定した引数が使われる)

ネイティブJSのクラスの実例

See the Pen JS's new 08_arrow by イイダリョウ (@i_ryo) on CodePen.

JSコード

var btn = document.getElementById('btn');
btn.addEventListener('click', (e) => {

class Ms {
  //コンストラクタ
   constructor(name, spec) {
    this.name = name;
    this.spec = spec;
  }
  //メソッド 
  say() {
    alert(this.name + "は" + this.spec);
  }
}

var zaku = new Ms("ザク", "通常の一倍");
 
var shar = new Ms("シャアザク", "通常の三倍");
  
var gufu = new Ms("グフ", "ザクとは違う");

//下に移動
zaku.say();
shar.say();
gufu.say();

}, false);

Msクラスの中で定義したsay()メソッドがzakuなどのインスタンスに継承されて実行できる。

詳細はこちらを参照

※参考:【JS】アロー関数のthisの挙動(プロトタイプとクラスの違い) - クモのようにコツコツと

クラスを使ったコンポーネントの書き方

extendsで継承

Reactのコンポーネントにクラスを使うにはクラス継承(extends)という機能を使う。

class クラス名 extends 継承するクラス {
  // クラスの処理
}

クラスからインスタンスにnewにメソッドを継承するように、extendsを使うと親クラスから子クラスに機能を継承できる。

※参考:クラスの継承 (extends を利用したクラス継承) - JavaScript プログラミング

ReactではReact.Componentというクラスが用意されてるので、この機能を継承する。

render()メソッドでレンダリング

クラスの中にはrender()メソッドを書く。

class クラス名 extends 継承するクラス {
  // コンポーネントをレンダリング
  render() {
    return <hoge></hoge> // JSXの処理
  }
}
  • render()メソッドの中、returnでJSXのタグを返す

render()メソッドは必須のメソッド。

render() メソッドは、クラスコンポーネントで必ず定義しなければならない唯一のメソッドです。

※参考:React.Component – React

この中にコンポーネントでレンダリングしたいJSXなどの処理を書いて、returnで返す。

コンストラクタの中にsuperキーワードを書く

クラスの中のコンストラクタ定義はネイティブJSのクラスと同じconstructor()メソッドだが、その中に必ずsuperキーワードが必要。

class クラス名 extends React.Component {
  // コンストラクタ設定
  constructor(props) {
    super(props);
    this.hoge = fuga;
  }

  // JSXレンダリング
  render() {
    return <hoge></hoge> // JSXの処理
  }
}

superキーワードってなんぞ?(かっこいい名前w)

super キーワードは、オブジェクトの親の関数を呼び出すために使用できます。

※参考:super - JavaScript | MDN

JavaScriptではsuperは親クラスのコンストラクタを参照します。(この例では、親クラスはReact.Component実装を指しています。)
重要なのは、JavaScriptはあなたがコンストラクターで親のコンストラクターを呼ぶまでthisは使わせてくれません。

※参考:なぜsuper(props) を書くの? - React界のカリスマ「Dan Abramov」のブログ - Qiita

ふむふむ。super()は親クラスを参照するよと。Reactの場合は親クラスReact.Componentを参照するよと。それによってthisが使えるよと。super()の前にthisを書いても使えないよと。

super()の引数がpropsじゃない場合はどういう動きになるか、などについても詳しく解説されている。

コンポーネントを読み込む

class クラス名 extends React.Component {
  // コンストラクタ設定
  constructor(props) {
    super(props);
    this.hoge = fuga;
  }

  // JSXレンダリング
  render() {
    return <hoge></hoge> // JSXの処理
  }
}

// コンポーネントの配置
let elm = (
    <クラス名 />
);

// DOMにレンダリング
ReactDOM.render(elm, Dom);

コンポーネントの配置からDOMへのレンダリングはいつもと同じだが、コンポーネント名の部分がクラス名になる!

クラスを使ったコンポーネントの書いてみる

実際に書いてみた。

See the Pen React - component class1 by イイダリョウ (@i_ryo) on CodePen.

前回のコンポーネント事始めを改造しているが、「こんにちは、くらす。」と表示されている部分がクラスを使ったコンポーネントになっている!

HTMLコード

<section>
    <h1>Reactのコンポーネント</h1>
    <div class="text">読み込み中…</div>
</section>

HTMLはいつもと同じ。. textでJSXをレンダリングする。

JSコード、まずはグローバルな変数を設定。

//DOM取得
const text = document.querySelector('.text');

//JSXに埋め込む値
const h2Text = 'コンポーネントのクラス';
const name = 'くらす';

//コンポーネントのスタイル
const bgColor = {
    background: '#fcc',    
    padding: '10px',
}
  • 変数textでDOM'.textを取得
  • 変数h2Textでh2に入れたいテキスト
  • 変数nameでpタグにnameとして入れたいテキスト
  • 変数bgColorに背景のCSSスタイル

次は本丸!クラスを使ったコンポーネント設定

//コンポーネント
class Hello extends React.Component {
    // コンストラクタ設定
    constructor(props) {
        super(props);
    }

    // JSXレンダリング
    render() {
        return <p style={bgColor}>こんにちは、{name}。</p>
    }
}
  • Helloクラスに親クラスReact.Componentを継承
  • constructor設定(super(props)のみ)
  • render()でJSXを設定。先ほどのbgColorのスタイルとnameのテキストを読み込む

コンポーネント配置

//JSXの中身
let elm = (
    <section className="h2_elem">
        <h2>{ h2Text }</h2>
        <div>
            <Hello />
        </div>
    </section>
);
  • 変数elmの中でJSXを設定しているが、その中にHelloコンポーネントを配置

Helloは先程のクラス名!

最後にtextのDOMにelmのJSXをレンダリング

ReactDOM.render(elm, text);

ここはいつもと変わらない。

今回は事始ということでコンポーネントにグローバル変数のbgColorのスタイルとnameのテキストを読み込むのみ。まだコンストラクタの設定をしていない。

JSコード全体

JSコード全体はこうなる

//DOM取得
const text = document.querySelector('.text');

//JSXに埋め込む値
const h2Text = 'コンポーネントのクラス';
const name = 'くらす';

//コンポーネントのスタイル
const bgColor = {
    background: '#fcc',    
    padding: '10px',
}

//コンポーネント
class Hello extends React.Component {
    // コンストラクタ設定
    constructor(props) {
        super(props);
    }

    // JSXレンダリング
    render() {
        return <p style={bgColor}>こんにちは、{name}。</p>
    }
}

//JSXの中身
let elm = (
    <section className="h2_elem">
        <h2>{ h2Text }</h2>
        <div>
            <Hello />
        </div>
    </section>
);
    
ReactDOM.render(elm, text);

最後に

f:id:idr_zz:20200423074425j:plain

ということでクラスを使ったコンポーネントを事始めました。

今回はまずクラスの書き方のおさらいし、前回の関数を使ったコンポーネントをReactでのクラスの書き方(React.Componentの継承、render()メソッド、コンストラクタのsuperキーワードなど)を知るところまででした。

次回はコンストラクタを設定してもっとバリエーションのある使い方を体験したいと思います。それではまた!!


※Reactでやってみたことまとめ
qiita.com