大多数 React 开发者对 useEffect 认识错误

发布: (2026年2月11日 GMT+8 17:30)
4 分钟阅读
原文: Dev.to

Source: Dev.to

Cover image for Most React Developers Get This Wrong About useEffect

在 React 中,useEffect 是一个强大的工具。它让你的组件能够“与” React 之外的事物交互——比如设置定时器、与服务器同步数据,或直接操作浏览器(例如更改页面标题)。当你需要与外部系统协作时,这非常有用。

但很多人在不需要的时候也会使用 useEffect。不必要的 useEffect 可能会:

  • 让代码更难阅读
  • 引入 bug
  • 使应用变慢

让我们了解 何时不需要 useEffect,以及在这种情况下应该怎么做。

Source:

不要使用 Effect 来转换数据

假设你要把名字和姓氏组合成全名。你可能会想到使用 Effect 来实现:

import { useState, useEffect } from 'react';

function Form() {
  const [firstName, setFirstName] = useState('Taylor');
  const [lastName, setLastName] = useState('Swift');
  // ❌ 不必要的 useEffect
  const [fullName, setFullName] = useState('');

  useEffect(() => {
    setFullName(firstName + ' ' + lastName);
  }, [firstName, lastName]);
}

这有点大材小用。你在用 Effect 来计算本可以在渲染过程中自然完成的内容。

更好的做法:

function Form() {
  const [firstName, setFirstName] = useState('Taylor');
  const [lastName, setLastName] = useState('Swift');
  // ✅ 不需要 Effect
  const fullName = `${firstName} ${lastName}`;
}

这样更简洁、更快,也更易于理解。当 firstNamelastName 变化时,React 会自动重新渲染组件,fullName 也会随之更新。

不要使用 Effect 处理用户事件

您同样不需要在按钮点击或输入更改后使用 Effect 来更新状态。

常见错误

function Counter() {
  const [count, setCount] = useState(0);
  const [double, setDouble] = useState(0);
  // ❌ Don't use Effect for derived state
  useEffect(() => {
    setDouble(count * 2);
  }, [count]);

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <div>Double: {double}</div>
    </>
  );
}

更佳做法

function Counter() {
  const [count, setCount] = useState(0);
  // ✅ No Effect needed
  const double = count * 2;

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <div>Double: {double}</div>
    </>
  );
}

您只需要存储那些会独立变化的状态。如果可以从已有状态计算出一个值,就直接计算即可。

何时需要 Effect?

当你处理 React 之外的事物时,需要使用 Effect。以下是一些示例:

从 API 获取数据

useEffect(() => {
  fetch('/api/user')
    .then(res => res.json())
    .then(data => setUser(data));
}, []);

订阅事件

useEffect(() => {
  function handleResize() {
    setWidth(window.innerWidth);
  }
  window.addEventListener('resize', handleResize);
  return () => window.removeEventListener('resize', handleResize);
}, []);

设置计时器

useEffect(() => {
  const id = setInterval(() => {
    console.log('Tick');
  }, 1000);
  return () => clearInterval(id); // Cleanup
}, []);

摘要

在使用 useEffect 之前,先问自己:

  • 我是否在与 React 之外的东西同步?
  • 或者我能否直接在渲染时计算它?

仅在数据无法计算时才使用状态。避免冗余的状态和不必要的 Effect。这会让你的 React 代码更简洁、更快,也更易于调试。

快速参考

是否需要 useEffect

  • 合并两个状态 – ❌ 否
  • 更新派生值 – ❌ 否
  • 响应用户点击 – ❌ 否
  • 从 API 获取数据 – ✅ 是
  • 设置计时器或间隔 – ✅ 是
  • 订阅外部事件 – ✅ 是

让 React 为你完成繁重的工作——仅在真正需要时才使用 Effect!

0 浏览
Back to Blog

相关文章

阅读更多 »

📦Redux 是什么?

如果你正在学习前端开发,尤其是使用 React,你可能听说过 Redux。它起初可能会让人感到困惑,但核心思想很简单……

Server Components 不是 SSR!

SSR 与 React Server Components 在开发者世界中,React Server Components(RSC)常被误认为只是另一种 Server‑Side Rendering(SSR)的形式。虽然两者……