React基础 第二十八章(将事件与Effect分开)

在React应用中,正确地区分事件处理函数和Effect是编写高效、可维护代码的关键。本文将探讨如何在事件处理和Effect之间做出选择,以及如何将非响应式逻辑从Effect中分离出来,提高应用的响应性和用户体验。

事件处理函数与Effect的区别

事件处理函数是针对用户交互的,例如点击按钮或提交表单。它们只在特定的用户操作触发时执行。相比之下,Effect是响应式的,它们在组件的props或state发生变化时自动执行,以保持与外部系统的同步。

正确的示例代码:

javascript 复制代码
function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  // 事件处理函数:只在用户点击"Send"按钮时执行
  function handleSendClick() {
    sendMessage(message);
  }

  // Effect:用于与聊天室服务器保持连接
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [roomId]);

  // ...
}

错误的示例代码

javascript 复制代码
function ChatRoom({ roomId }) {
  const [message, setMessage] = useState('');

  // 🔴 错误:在Effect中处理用户点击事件
  useEffect(() => {
    const sendButton = document.getElementById('sendButton');
    sendButton.addEventListener('click', () => {
      sendMessage(message);
    });

    return () => {
      sendButton.removeEventListener('click', () => {
        sendMessage(message);
      });
    };
  }, [message]); // 这里的依赖项可能会导致Effect在每次message变化时重新绑定事件
}

在这个错误的示例中,事件处理逻辑被错误地放在了Effect中。这样做有几个问题:

  1. 每次message变化时,都会重新为发送按钮绑定点击事件监听器,这是不必要的,并且可能导致内存泄漏。
  2. 事件处理函数应该直接绑定到元素上,而不是在Effect中进行绑定和解绑。
  3. 在Effect的清理函数中,由于每次都创建了一个新的函数实例,removeEventListener实际上不会移除之前添加的事件监听器。

如何选择使用事件处理函数还是Effect

当你的代码需要响应用户的特定操作时,应该使用事件处理函数。如果代码需要与组件的props或state保持同步,无论用户是否进行了交互,那么应该使用Effect。

使用Effect Event来隔离非响应式逻辑(实验性API,目前react稳定版不能用)

Effect Event是一个特殊的Hook,它允许你在Effect中执行非响应式逻辑,同时能够访问最新的props和state。

技巧示例代码:

javascript 复制代码
const onConnected = useEffectEvent(() => {
  showNotification('Connected!', theme);
});

useEffect(() => {
  const connection = createConnection(serverUrl, roomId);
  connection.on('connected', onConnected);
  connection.connect();
  return () => connection.disconnect();
}, [roomId]); // 不需要将onConnected作为依赖项

在这个例子中,我们希望在连接到聊天室时显示通知,但不希望每次theme变化时都重新连接。因此,我们没有将theme作为Effect的依赖项。

相关推荐
码云之上3 分钟前
换模型之后,Chatbot 为什么要自己做 compact?
前端·agent·前端工程化
星栈17 分钟前
自定义 UI-UX-Pro-Max 的 CSV 知识库,把 AI 生成的后台拉回行业该有的样子
前端·agent·weui
研☆香29 分钟前
简单的图片上传 删除 预览
前端
ITresearchGuest35 分钟前
我用 AI 一小时写了一个世界杯数据可视化平台|前端 VibeCoding 初体验
前端·人工智能·信息可视化
慧一居士2 小时前
Vite项目中使用Less步骤,详细使用示例
前端·css
花间相见2 小时前
【LangChain组件03】—— LangChain Agents 执行与状态:工作流程与状态管理实战
java·前端·langchain
kyriewen2 小时前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试
计算机魔术师2 小时前
700吉瓦「幽灵用电」:美国AI数据中心的抢电闹剧正在失控
前端
IT_陈寒3 小时前
JavaScript数组排序踩的坑,差点让我加班到凌晨
前端·人工智能·后端
风骏时光牛马3 小时前
提示词工程:大模型交互的核心构建艺术
前端