株式会社WOWNエンジニアチームです。
前回、簡単なWebシステムの一連の処理を作成しました。
「Webページにあるボタンを押したらサーバーにアクセスし、ボタンがクリックされた記録を1回分増やす」という処理です。これには「ビューからAPIエンドポイントにアクセスし、コントローラが呼び出されてサーバーの記録を操作」…といった流れがありました。
結果、前回は以下のような簡単なReactファイルを作成しました。
export default function CountButton() {
return (
<button onClick={() => post('/api/system/count/increment')}>
クリック
</button>
);
}
今回の話は前回の逆順で、「サーバーに保存した総クリック数の記録を、Reactページで表示するにはどうすればいいのか?」という内容です。
ステートという”箱”
今回、サーバーからクリック回数という数値を受け取ろうとしていますが、当然の話、Reactページはサーバーからどんな数値がやってくるかを知りません。0かもしれないし、1かもしれないし、9999かもしれません。
こういった外部の情報によって変化しうる状態のことを「動的」と呼んだりします。
例えばこのブログの記事の内容も、我々がどんな文字を書いて保存するかによって変化しますから、動的な内容です。
動的な数値をReactページで表示するにはどうすればいいのか?
これにはReactが持つ「ステート」という機能を使います。
前回のコードにステートを追加してみましょう。
import { useState } from 'react'
export default function CountButton() {
const [clickCount, setClickCount] = useState(0)
return (
<button onClick={() => post('/api/system/count/increment')}>
クリック
</button>
);
}
コードにconst [clickCount, setClickCount] = useState(0)という内容が増えていますね。これで「clickCount」というステートを用意したことになります。
ステートをざっくり紹介すると、好きな値を入れることができる変数(箱)です。箱の中に何を入れてもかまいません(ステートの作り方によって、箱の中に入れられるデータの形式などを制限することはできます)。ただし、箱の入り口が1箇所しかありません。「clickCount」という箱に数値を入れられるのは「setClickCount」という関数だけです。特に値を更新していない場合、初期値には「useState(0)」に書かれている「0」という数値が入っています。
どういうことなのか、以下の例で見てみましょう。
ステートを操作する
clickCountというステートを使うと、以下のような文章を作ることができます。
<p>クリックされた回数は{clickCount}回です</p>
clickCountというステートにどんな数値を入れるかによって、動的に回数の数値が変化しうる文章です。
clickCountに入っている値が0でも9999でも、問題なく表示できます。初期値は0だったので、このままでは「クリックされた回数は0回です」と表示されます。
では、clickCountに入っている数値を入れ替えるにはどうすればいいのか?
ここでsetClickCountの出番です。
<p>クリックされた回数は{clickCount}回です</p>
<button onClick={setClickCount(100)}>
クリック
</button>
この例では、ボタンを押した際、setClickCount(100)という関数が実行されるようになっています。
setClickCountの使い方は実に単純明快で、setClickCount({好きな値})を実行することで、clickCountというステートに好きな値を入れることができます。
setClickCount(9999)と書けば、Reactページの{clickCount}の部分で「9999」と表示されますし、
setClickCount(‘こんにちは’)と書けば、{clickCount}には「こんにちは」と表示されます。
いよいよサーバーと連動
さて、これで今回の目的はハッキリしました。クリック回数を表示するには、サーバーから情報を取得し、得たデータをsetClickCount()を使って適用すればよいだけです。
コントローラとルートの実装は今回は丸々省略しまして、結果出来上がるReactのビューファイルの内容は次のようになります。
import {useState, useEffect} from 'react';
import axios from 'axios';
export default function CountButton() {
const [clickCount, setClickCount] = useState(0)
useEffect(() => {
axios.get('api/system/count/get')
.then(response => {
setClickCount(response.data);
})
}, []);
return (
<p>クリックされた回数は{clickCount}回です</p>
<button onClick={() => post('/api/system/count/increment')}>
クリック
</button>
);
}
「useEffect」や「axios」などの新しい記述が増えていますね。
useEffectは、特定のタイミングで中の関数を実行するReactの機能、axiosはAPIから情報を取得するために必要なライブラリ(他の誰かが作ってくれたプログラム)です。今回の話とはあまり関係がないので、今は「そういう呪文があるんだな」ぐらいで見ておいてください。
axiosの機能で’api/system/count/get’というAPIにアクセスし、そのレスポンス(サーバーからの返答)が「response.data」という形式で返ってきます。これをさきほどのsetClickCountに対して使うことで、「サーバーから取得した値がclickCountステートに適用された」という状態が出来上がるわけです。
ただし、この例だとクリック回数を取得するのはReactページを読み込んだ初回だけです。ボタンをクリックするとサーバー上のクリック回数の記録は増えますが、clickCountステートの数値はページを読み込みなおすまで更新されません。
「ボタンをクリックするたびにクリック回数を更新したい」などの要求を叶えるためには、「更新タイミング」「状態管理」などのReactの別の話をする必要があります。
次回に続きます。
WEB制作・ITに関するお悩みや
ご質問等お気軽にご相談ください