美文网首页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