الگوی رایج و نادرست این است: یک state می‌سازیم، یک useEffect می‌نویسیم تا با تغییر یک مقدار دیگر آن را به‌روز کند. نتیجه یک رندر اضافه و احتمال ناهماهنگی است. مستندات ری‌اکت صریحاً می‌گوید برای محاسبهٔ داده از روی props یا state به effect نیاز ندارید.

نسخهٔ نامناسب

function Cart({ items }) {
  const [total, setTotal] = useState(0);

  useEffect(() => {
    setTotal(items.reduce((s, i) => s + i.price, 0));
  }, [items]);

  return <p>جمع: {total}</p>;
}

نسخهٔ بهتر

function Cart({ items }) {
  const total = items.reduce((s, i) => s + i.price, 0);
  return <p>جمع: {total}</p>;
}

اگر محاسبه سنگین است، به‌جای effect از useMemo استفاده کنید؛ اما اول اندازه بگیرید، چون بیشتر محاسبه‌ها آن‌قدر ارزان‌اند که memo لازم نیست.

پس useEffect برای چیست؟

  • همگام‌سازی با دنیای بیرون از ری‌اکت: اشتراک‌ها، تایمر، رویدادهای window، اتصال شبکه.
  • کارهایی که باید «چون کامپوننت نمایش داده شد» انجام شوند؛ نه «چون کاربر کلیک کرد» (آن‌ها در event handler می‌روند).