React Hooksでタイマーを実装してみる。

状態が頻繁に更新されるコンポーネントということで、タイマーを実装してみる。とりあえず、実装すると以下のようになる。

import React from 'react';

const Timer = () => {

    const [time, setTime] = React.useState(0);

    React.useEffect(() => {
      const id = setInterval(() => {
        setTime(time + 1);
      }, 1000);
      return () => clearInterval(id);
    }, [time]);

    return (
      <p>Time: {time}</p>
    );
};

export { Timer }

React.useStateで必要な状態timeを宣言し、React.useEffectで副作用のあるtimeの更新処理を宣言している。

ただ、これだと、timeを更新するたびに、useEffectの関数も更新する必要があり、あまり効率が良くない。(ちなみに関数を更新しないと、クロージャによってtimeの値が変わらないのでtimeが更新されない。)特にfpsを稼ぎたい場合などはつらい。

どうすればいいんだと思ったら、公式に書いてあった。

import React from 'react';

const Timer = () => {

    const [time, setTime] = React.useState(0);

    React.useEffect(() => {
      const id = setInterval(() => {
        setTime(t => t + 1);
      }, 1000);
      return () => clearInterval(id);
    }, []);

    return (
      <p>Time: {time}</p>
    );
};

export { Timer }

setTimeには更新のための関数を設定できるらしい。