[React] useEffect - problem: depending On State Mutated In The useEffect

Let say we have a simple counter app:

import { useEffect, useState } from "react";

function useStopwatch() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("useStopwatch");
    const interval = setInterval(() => {
      console.log(`Count = ${count}`);
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, [count]);

  return count;
}

export default function App() {
  const count = useStopwatch();
  return (
    <div className="App">
      <h2>{count}</h2>
    </div>
  );
}

Everytime, `count` get mutated, `useStopwatch` will be trigger to re-run:

This is because, `useEffect` is deps on `count`. 

 

The way we can solve the problem by decouple the `count` with `useEffect`

function useStopwatch() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("useStopwatch");
    const interval = setInterval(() => {
      console.log(`Count = ${count}`);
      setCount((prev) => prev + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return count;
}

setCount((prev) => prev + 1);

Custom hook is triggered much less times and we no longer deps on mutated state `count`

posted @ 2022-10-26 14:58  Zhentiw  阅读(29)  评论(0)    收藏  举报