useEffect

react的逃生舱

作用

和非React的外部系统交互,比如发起请求(建立服务器连接)、调用浏览器API(设置定时器)等

useEffect(setup, dependencies?)

setup函数包含两部分:

  • setup code:组件挂载(插入到DOM中)时调用

  • cleanup code(可选):组件卸载(从DOM中移除)时调用,主要用于清除遗留逻辑,比如清除定时器、断开服务器连接等

执行顺序:

  • 首次挂载(开发模式):setup => cleanup => setup

  • 首次挂载(生产模式):setup

  • 重新渲染:cleanup(旧值) => setup(新值)

  • 组件卸载:cleanup

After every re-render with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values.

示例

import { useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) {
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [serverUrl, roomId]);
  // ...
}

关键点

  • 只可在组件顶层执行,不可放到循环或条件中

  • 如果不和外部系统通信,没必要使用Effect

  • 使用useLayoutEffect代替:(没理解~)

If your Effect wasn’t caused by an interaction (like a click), React will let the browser paint the updated screen first before running your Effect. If your Effect is doing something visual (for example, positioning a tooltip), and the delay is noticeable (for example, it flickers), replace useEffect with useLayoutEffect.

Even if your Effect was caused by an interaction (like a click), the browser may repaint the screen before processing the state updates inside your Effect. Usually, that’s what you want. However, if you must block the browser from repainting the screen, you need to replace useEffect with useLayoutEffect.

Last updated