反応フックでJavaScriptスケジューリングメソッドを使用する方法


時には、特定の時間、または指定された間隔で関数を実行することができます.この現象を呼ぶ.scheduling a function call .
JavaScriptは2つのメソッドを提供します.
  • setinterval
  • settimeout
  • これらのスケジューリングメソッドを使用するreactJs 簡単です.しかし、私たちは効果的にそれらを使用するいくつかの小さなgotchasを認識する必要があります.この記事では、私たちはsetInterval and setTimeout メソッドreactJS コンポーネント.
    簡単にビルドしましょうReal-time Counter and Task Scheduler 使用法を示す.

    setintervalとは


    The setInterval メソッドを使用すると、定期的に関数を実行できます.これは、時間間隔の後に関数を実行して起動し、継続的にその間隔で繰り返します.
    ここでは、ブラウザコンソールにいくつかのログを印刷する関数を実行するために、1秒間隔(1000ミリ秒)を定義しました.
    const timerId = setInterval(() => {
      console.log('Someone Scheduled me to run every second');
    }, 1000);
    
    The setInterval 関数コールはtimerId を使用することでタイマーを取り消すことができますclearInterval メソッド.setintervalの呼び出しを停止します.
    clearInterval(timerId).
    

    settimeoutとは


    The setTimeout メソッドを使用すると、関数を実行できますonce 時間の間隔の後.ここでは、2秒後にブラウザコンソールで何かをログオンする機能を定義しました.
    const timerId = setTimeout(() => {
      console.log('Will be called after 2 seconds');
    }, 2000);
    
    setintervalのように、settimeoutメソッドコールはtimerId . このIDは、タイマーを停止するために使用することができます.
    clearTimeout(timerId);
    

    リアルタイムカウンタ


    Aを造りましょうreal-time counter アプリケーションの使用方法を理解するsetInterval 反応アプリケーションの方法.リアルタイムカウンタを起動し、カウンタを停止するトグルボタンがあります.カウンタ値は、ユーザーがカウンタを起動すると、毎秒の終わりに1ずつ増加します.ユーザーは、カウンタを停止したり、初期値、ゼロからカウンタを再開することができます.
    我々はいくつかの組み込みフックの反応から使用されますが、同じ反応は、同様に反応クラスのコンポーネントを使用して可能です.
    これは、コンポーネントがどのように動作するかです.


    Figure 1: Using setInterval and React Hooks


    ステップ1:輸入によって始めましょうReact そして、2つのビルトインフック.useState and useEffect .
    import React, { useState, useEffect} from "react";
    
    ステップ2:2つの状態変数が必要です.最初のスタートストップのトグルを追跡するreal-time ボタンと2番目のcounter 自身.を使って初期化しましょうuseState フック.
    フックuseState ペアを返します.最初は現在の状態、2番目はupdater関数です.通常、配列の破壊を利用して値を割り当てます.引数を使用して初期状態値を渡すことができます.
     const [realTime, setRealTime] = useState(false);
     const [counter, setCounter] = useState(0);
    
    ステップ3:フックuseEffect 状態値の変更、任意の種類のサブスクリプション、ネットワーク要求などの任意の種類の副作用を処理するために使用されます.最初に、実行時に呼び出される関数と、フックを実行する値の配列を引数とします.
    すべてのレンダリングが完了した後にデフォルトで実行されます.ただし、特定の値が2番目のパラメータとして渡すことによって変更されるたびに実行できます.また、空の配列を2番目のパラメータとして渡すことで、一度だけ実行できます.
    この場合、私たちはuseEffect フックは、ユーザーがリアルタイムボタン(開始と停止)を切り替えます.我々は、間隔を開始するときrealTime 状態変数はtrueであり、状態変数値がfalseの場合は間隔をキャンセル/停止します.以下に、コード構造がどのように見えるかを示します.
    useEffect(() => {
      let interval;
      if (realTime) {
        interval = setInterval(() => {
          console.log('In setInterval');
          // The logic of changing counter value to come soon.
        }, 1000);
      } else {
         clearInterval(interval);
      }
      return () => clearInterval(interval);
    }, [realTime]);
    
    私たちはsetInterval 内部メソッドuseEffect フックと同じです.componentDidMount クラスコンポーネントのライフサイクルメソッド.この時点で、1秒間隔の最後にログを出力します.我々は2つのケースでタイマーをクリアしている.まず、realTime 状態変数はfalseで、2番目の要素はアンマウントされます.
    ステップ4:カウンタを増やす時間.それを行う最も簡単な方法は、setCounter このようにカウンタのインクリメント値を設定します.
    setCounter(counter => counter + 1);
    
    しかし、ここで重要なことに気付きましょう.setInterval メソッドはclosure , したがって、setintervalが予定されるとき、それは時間のその正確な瞬間のカウンタの値を使用します.これは私たちを感じさせるでしょうuseState フックは、内部で更新されていませんsetInterval メソッド.
    このコードを見てください.
    useEffect(() => {
      let interval;
      if (realTime) {
        interval = setInterval(() => {
          console.log('In setInterval', counter);
        }, 1000);
        setCounter(100);
      } else {
        clearInterval(interval);
      }
       return () => clearInterval(interval);
    }, [realTime]);
    
    The console.log('In setInterval', counter); 行のログ0 カウンタ値を0に設定しても100 . コンポーネントを再描画することなく、状態変数の変更された値を追跡することができます.もう一つのフックがあります.useRef この目的のために.useRef は、そのボックスの中で変更可能な値を保持することができる.current プロパティ.私たちはref 直接使用counter.current = 100 . チェックアウトthis awesome article Bhanu teja pachipulusuによって学ぶuseRef 詳細にフック.
    それで、我々は最初にそれを他のフックと一緒に輸入する必要があります.
    import React, { useState, useEffect, useRef } from "react";
    
    そして、useRef フックを参照して、同期を作成します.
    const countRef = useRef(counter);
    countRef.current = counter;
    
    この後、countRef.current の代わりに値counter に渡される関数の内部値setInterval メソッド.
    useEffect(() => {
      let interval;
      if (realTime) {
        interval = setInterval(() => {
          let currCount = countRef.current;
          setCounter(currCount => currCount + 1);
        }, 1000);
      } else {
          clearInterval(interval);
      }
     return () => clearInterval(interval);
    }, [realTime]);
    
    今、我々はすべての時間のカウンタの更新(現在の)値を取得することが保証されます.
    ステップ5:次のステップは、スタートストップボタンを切り替えて、カウンタをリセットするための2つの機能を作成することです.
    const manageRealTime = () => {
      setRealTime(!realTime);
    }
    
    const reset = () => {
      setCounter(0);
    }
    
    ステップ6 :最後のステップはレンダリング部分を作成することです.
    <div className={style.btnGrpSpacing}>
      <Button
        className={style.btnSpacing} 
        variant={realTime? 'danger' : 'success'} 
        onClick={() => manageRealTime()}>
          {realTime ? 'Stop Real-Time': 'Start Real-Time'}
      </Button>
      <Button 
        className={style.btnSpacing} 
        variant= 'info'
        onClick={() => reset()}>
          Reset Counter
      </Button>
    </div>
    
    <div className={style.radial}>
      <span>{counter}</span>
    </div>
    
    以上です.我々は、リアルタイムのコンポーネントの使用setInterval とフックuseState , useEffect and useRef ).

    タスクスケジューラ


    さて、次のような別の反応コンポーネントを作成します.Task Scheduler これは、1秒ごとに2秒後にカウンタをインクリメントするタスクをスケジュールします.このスケジューラは、ユーザーがボタンをクリックして再度スケジュールするか、カウンタをリセットするまで何もしません.
    これは、コンポーネントがどのように動作するかです.


    Figure 1: Using setTimeout and React Hooks


    と同じようにsetInterval 方法、我々はsetTimeout 内部メソッドuseEffect フック.また、コンポーネントのアンマウント時にタイマーをクリアします.
    useEffect(() => {
      const timer = setTimeout(() => {
        console.log('setTimeout called!');
      }, 1000);
    
      return () => clearTimeout(timer);
    }, []);
    
    setintervalはsetintervalと同様です.したがって、我々は状態変数counter SetTimeoutメソッド内の現在の値を反映しません.
    useEffect(() => {
      const timer = setTimeout(() => {
        console.log(counter);
      }, 2000);
      setCounter(100);
    return () => clearTimeout(timer);
    }, []);
    
    上記の場合、カウンタ値は残ります0 に値を設定しても100 .
    この問題は以前の例でどのように見たかに似ています.フックを使うuseRef .
    useEffect(() => {
      const timerId = schedule();
      return () => clearTimeout(timerId);
    }, []);
    
    const schedule = () => {
      setScheduleMessage('Scheduled in 2s...');
        const timerId = setTimeout(() => {
          let currCount = countRef.current;
          setCounter(currCount => currCount + 1);
          console.log(counter);
      }, 2000);
    
       return timerId;
    }
    
    ここでは、関数schedule を返します.The schedule 関数は、リファレンス(ref)から現在の値を使用し、それに応じてカウンタ値を設定します.

    デモとコード


    ここから両方のコンポーネントで遊ぶことができます.Demo: JavaScript scheduling with React Hooks
    この記事で使用されるすべてのソースコードはDemolab Gitrepoの一部ですdirect source file link ). してください/フォーク/クローンを無料でお気軽に.

    アタパス / ディーララボ


    Demolabは、Javascript(ReactJs)、API(NetlifyとAWS)と予め構築されたマークアップ(Gatsby)を使用しているJamstackの力を理解するためにつくられる私のファンタジープロジェクトです。


    ディーララボ


    Demolabは、私のファンタジープロジェクトですJAMstack 使用JavaScript(Reactjs) , API(Netlify and Aws) とビルド済みのマークアップ(Gatsby ).
  • Demolabはホストされますhttps://demo.greenroots.info/
  • 詳細はこちらをご覧ください.Hey, I have made a demolab using JAMstack
  • さえずりで私に連絡してください

  • 星でこのプロジェクトを支持したすべてのstargazersに、多くの感謝⭐)



    View on GitHub

    要約する


    まとめる.
  • setInterval and setTimeout JavaScriptで関数呼び出しをスケジュールする方法があります.もっと読むfrom here .
  • があるclearInterval and clearTimeout スケジューラメソッドのタイマーを取り消す方法.
  • これらのスケジューラメソッドは、反応コンポーネント内の他のJavaScript関数と同様に使用できます.
  • setIntervalメソッドとsetTimeoutメソッドはクロージャです.したがって、スケジュールされたとき、スケジュールされた時点で状態変数の値を使用します.コンポーネントが再レンダリングされると、新しいクロージャが作成されますが、最初に閉じられた値は変更されません.この状況を解決するには、useRef 状態変数の現在値を取得するフック.あなたはさらにこの解決策について読むことができますfrom this GitHub issue .
  • あなたが役に立つこの記事を見つけてください.閉じるこの動画はお気に入りから削除されています.
  • Understanding JavaScript Closure with example
  • A Notification Timeline using React
  • Understanding Dynamic imports, Lazy and Suspense using React Hooks
  • Adding a Table row dynamically using React Hook
  • Being Reactive - Usage of Virtual DOM and DOM Diffing
  • Step by Step Guide: Blend Redux with ReactJs
  • 行く前に.


    これまで読んでくれてありがとう!あなたは@ Twitterの上で@コメントすることができますか、または以下の自由を感じる.
    私はJavaScript、Web開発、およびJamstackのほとんど私の学習とサイドプロジェクトについて書きます.お気軽にチェックアウトblog site .
    それがあなたにとって有用であるならば、同様に/共有してください、それは同様に他にも達します.