美文网首页React 重新学习前端技术
React 文档再学习 7 使用 Effects 进行同步

React 文档再学习 7 使用 Effects 进行同步

作者: 吴摩西 | 来源:发表于2022-11-28 16:00 被阅读0次

Effects 帮助开发者跟 React 外部沟通,例如同步状态给非 React 组件,跟服务器建立连接。或者当组件出现在页面时,发送一些日志。

在 React 组件中,包含两种代码:

  • 渲染 (rendering) 代码,将 props 和 state 转换成 JSX。类似于数学公式,仅仅计算出结果,不做任何其他事情。
  • 事件响应,事件响应不仅计算页面元素,也可能发送 HTTP POST 请求,或者跳转到其他页面。事件响应会因为特定的用户行为(例如点击按钮或者在 input 中输入)产生副作用 (side effect,修改程序状态)

Effect 可以让开发者在由于渲染本身触发,而不是用户特定行为触发的副作用。例如当一个聊天窗口出现在屏幕上时,连接到远端聊天服务器。Effect 会在渲染结束并且更新屏幕后执行。是跟外部系统(例如网络或者第三方组件库)同步的好时机。

不应该使用 useEffect 的地方

  • Effect 不应当用于在 React 内部同步状态。
  • 不应该在 props 改变时,在组件内部更新 state。
  • 不要在 useEffect 中执行链式的数据计算或者状态更新。因为组件和它的子组件都会在计算时重新渲染。
  • 不要在 effect 中初始化系统,会在 dev 模式下执行两次。
  • 不要在 effect 中调用父组件响应函数,会引起多次渲染。
  • 不要在 effect 中获取数据并更新父组件状态。在 react 中,状态变化都是自顶向下,在子组件中更新父组件,导致状态变化难以追踪,应当在父组件中获取数据并传递给子组件。
  • 不要在 effect 中监听外部 store,react 中有专有的 hook useSyncExternalStore
  • 不要直接在 effect 中 fetch 数据,推荐使用第三方组件,如果自己执意获取数据。需要处理好两次加载的问题。

Effect 的生命周期

所有的 react 组件都有如下的生命周期

  • mount,当组件出现在屏幕上。
  • update,组件收到新的 props, state 时,进行更新。一般是由于用户的交互产生的。
  • unmount,当组件从屏幕上移除。
const serverUrl = 'https://localhost:1234';

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

一般可以理解成,当组件 mount 时,react 开始与外部系统同步,当组件 unmount 时,react 停止与外部系统同步。
如果不指定 dependency array,effect 会在每次 render 后执行。

去除多余的 dependency

function ChatRoom({ roomId }) {
  const [messages, setMessages] = useState([]);
  useEffect(() => {
    const connection = createConnection();
    connection.connect();
    connection.on('message', (receivedMessage) => {
     // 下面的代码会产生额外的 dependency
     // setMessages([...messages, receivedMessage]);
      setMessages(msgs => [...msgs, receivedMessage]);
    });
    return () => connection.disconnect();
  }, [roomId]); // ✅ All dependencies declared
  // ...

相关文章

网友评论

    本文标题:React 文档再学习 7 使用 Effects 进行同步

    本文链接:https://www.haomeiwen.com/subject/qthcfdtx.html