在开发环境中,React 将立即运行并额外清理一次 Effect。这就是为什么你会看到 "✅ 连接中..." 打印了两次。这能够确保你不会忘记实现清理功能。
想要仔细学习这个主题的内容吗?阅读 使用 Effect 进行同步 以了解如何将组件与外部系统同步。
阅读更多
你可能不需要 Effect
Effect 是 React 范式中的一种脱围机制。它们可以“逃出” React 并使组件和一些外部系统同步。如果没有涉及到外部系统(例如,需要根据一些 props 或 state 的变化来更新一个组件的 state),不应该使用 Effect。移除不必要的 Effect 可以让代码更容易理解,运行得更快,并且更少出错。
有两种常见的不必使用 Effect 的情况:
不必为了渲染而使用 Effect 来转换数据。
不必使用 Effect 来处理用户事件。
例如,不需要 Effect 来根据其他状态调整某些状态:
function Form() { const [firstName, setFirstName] = useState('泰勒'); const [lastName, setLastName] = useState('斯威夫特'); // 🔴 避免:多余的 state 和不必要的 Effect const [fullName, setFullName] = useState(''); useEffect(() => { setFullName(firstName + ' ' + lastName); }, [firstName, lastName]); // ...}
相反,在渲染时进行尽可能多地计算:
function Form() { const [firstName, setFirstName] = useState('泰勒'); const [lastName, setLastName] = useState('斯威夫特'); // ✅ 非常好:在渲染期间进行计算 const fullName = firstName + ' ' + lastName; // ...}
你 的确 可以使用 Effect 来和外部系统同步。
想要仔细学习这个主题的内容吗?阅读 你可能不需要 Effect 以了解如何移除不必要的 Effect。
阅读更多
响应式 Effect 的生命周期
Effect 的生命周期不同于组件。组件可以挂载、更新或卸载。Effect 只能做两件事:开始同步某些东西,然后停止同步它。如果 Effect 依赖于随时间变化的 props 和 state,这个循环可能会发生多次。
这个 Effect 依赖于 roomId props 的值。props 是 响应值,这意味着它们可以在重新渲染时改变。注意,如果 roomId 更改,Effect 将会 重新同步(并重新连接到服务器):