クモのようにコツコツと

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

【React】JSXレンダリングとタイマー処理(setInterval())の関係を理解する

Reactの続きです。前回は色々なループの書き方をやってみました。今回は一つ前の投稿でも触れたタイマー処理を絡めて、JSXレンダリングとの関係を理解したく。それでは行きましょう!

【目次】

前回記事
※参考:【React】ループの書き方(for文エラー回避、配列、map()) - クモのようにコツコツと

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

JSのタイマー処理(setInterval())とは

今回も掌田さんの「React.js & Next.js超入門」を参考に進める。Reactとタイマー処理の関係に入った。

React.js&Next.js超入門

React.js&Next.js超入門

タイマー処理とは時間差で処理を実行すること。タイマー予約みたいな。

こちらの記事で触れたようにJSのタイマー処理はsetTimeout()(1回実行)とsetInterval()(複数回実行)の2種類。

※参考:【JS】setTimeout()とsetInterval()の違い(一回と複数回) - クモのようにコツコツと

今回はsetInterval()を使う。

setInterval(処理, 時間);

第一引数は処理で第二引数が時間。一定の時間ごとに処理を繰り返し実行する。

setInterval()の中にReactコードを書く

前回の「羊が何匹」のタイマー処理とReactに合体させるとこうなる。

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

「Run Pen」を押すと1秒に1匹ずつ羊の数を数え始める。

HTMLコード

<section>
    <h1>Reactとタイマー処理</h1>
    <div class="text">読み込み中…</div>
</section>

いつもと同じシンプルな構成。.textをJSXで書き換える。今回はここが1秒ごとに更新されている。

JSコード

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

//JSXに埋め込む値
const h2Text = "羊は何匹?";

//カウントの初期値
let counter = 0;

//タイマー処理
setInterval(() => {
    
    //カウントアップ
    counter++;

    //JSXの中身
    const elm = (
    <section className="h2_elem">
        <h2>{ h2Text }</h2>
        <p>「羊が{ counter }匹…」</p>
    </section>
    );

    //レンダリング
    ReactDOM.render(elm, text);
    
}, 1000);
  • 変数text. textのDOMを取得
  • 変数h2Textにh2タグに入れたいテキストを入れる
  • 変数counterでカウントの初期値0
  • setInterval()の第一引数に処理
    counterを一つずつカウントアップ
    変数elmでJSXを設定
    h2タグにh2Textを入れる
    pタグの中のcounterにカウントを入れる ReactDOM.render()メソッドでelmtextにレンダリング
    setInterval()の第二引数は時間で1000ミリ秒(=1秒)

これで1秒ごとに羊の数が増えて行く!

setInterval()の中に処理を丸々書いているので若干setInterval()の見通しは悪い。

JSXをsetInterval()の外に移動(動かない!)

setInterval()の中をスッキリさせるために、JSXの部分を外部に移動してみる。

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

ありゃ?羊が0匹のまま、数が増えないぞ?

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

//JSXに埋め込む値
const h2Text = "羊は何匹?";

//カウントの初期値
let counter = 0;

//JSXの中身
const elm = (
    <section className="h2_elem">
        <h2>{ h2Text }</h2>
        <p>「羊が{ counter }匹…」</p>
    </section>
);

//タイマー処理
setInterval(() => {
    
    //カウントアップ
    counter++;

    //レンダリング
    ReactDOM.render(elm, text);
    
}, 1000);
  • 変数elmのJSX設定をsetInterval()の外に移動

ReactDOM.render()は1秒に一回elmを読みに行っているはずなのだが、elmのJSXは変数が定義した時に一回実行されるのみでcounterの更新を行わない、ということだ。

処理を全て外部の関数に書いて読み込む

ここからは本にはない内容だが実験。処理を全部外部の関数に書いて、それをsetInterval()に読み込むとどうなるか。以前の実験では問題なく成功した方法。

※参考:【JS】setTimeout()とsetInterval()の違い(一回と複数回) - クモのようにコツコツと

やってみたのがこちら。

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

おお!今度はちゃんと数を数えている!

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

//JSXに埋め込む値
const h2Text = "羊は何匹?";

//カウントの初期値
let counter = 0;

let hitsuji = () => {
    
    //カウントアップ
    counter++;

    //JSXの中身
    const elm = (
    <section className="h2_elem">
        <h2>{ h2Text }</h2>
        <p>「羊が{ counter }匹…」</p>
    </section>
    );

    //レンダリング
    ReactDOM.render(elm, text);
    
};

//タイマー処理
setInterval(hitsuji, 1000);
  • 変数hitsujiの中は無名関数でここに処理を書く
  • setInterval()の第一引数で関数hitsujiを読み込む

この場合は1秒に一回関数hitsujiを実行するため、カウントとJSXレンダリングが同時に行われる。setInterval()の中もスッキリ。処理が長い場合はこの書き方が良さそう。

(関数名にカッコを付けないのは実行のタイミングを制御するため。詳しくはこちらを参照)

※参考:【JS】setTimeout()とsetInterval()の違い(一回と複数回) - クモのようにコツコツと

最後に

ということでタイマー処理をする時にはJSXも同じタイミングで実行する必要がわかりました。JSXをsetInterval()の中に書くか、全体を外部の関数に書いて同時に実行するのが良さそうです。

次回はイベント処理!これも良く使うはずなので楽しみです。それではまた!


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