为了账号安全,请及时绑定邮箱和手机立即绑定

React中的`useEffect`:最佳实践、常见陷阱及现代JavaScript应用技巧

React 的 useEffect 钩子是功能组件开发的基石,使开发人员能够处理诸如数据获取、DOM 操作和订阅之类的副作用。尽管它功能强大,往往被误解,导致性能瓶颈和难以追踪的 bug。本文将揭示使用 useEffect 的最佳做法、需要避开的常见陷阱,以及如何利用现代 JavaScript 让你的 React 代码更高效。

同时,及时了解支持 React 的核心 JavaScript 语言的更新也非常重要。我的电子书 "JavaScript: 从 ES2015 到 ES2023" 是一个很好的资源,可以让你更深入地了解现代 JavaScript 特性,这些特性对于 React 开发来说必不可少。

咱们开始吧!

……

等等

什么是useEffect呢?

useEffect 是一个钩子,允许你在函数组件中执行副作用。它替代了 componentDidMountcomponentDidUpdatecomponentWillUnmount 等 React 的生命周期方法。

语法的概述:

    useEffect(() => {
      // 副作用逻辑
      return () => {
        // 清理逻辑(可选)
      };
    }, [dependencies]);

全屏或退出

……

使用useEffect的一些最佳实践

1. 正确地使用依赖项

依赖列表确保效果仅在特定值变化时才会执行。请务必包含效果中使用的所有变量。缺少依赖项可能导致错误或数据过时。

例如:

    useEffect(() => {
      console.log(`当前计数是: ${count}`);
    }, [count]); // 仅在 `count` 变化时才会执行

点击全屏,然后退出全屏

小贴士:使用如 eslint-plugin-react-hooks 这样的代码规范插件来捕捉遗漏的依赖项。

此处省略内容

2. 多方面独立效果

每个 useEffect 应该只处理一个要点。如果在一个 useEffect 中加入多个职责,会让代码更难调试和维护。

例子:

    useEffect(() => {
      console.log("组件已加载");
    }, []);

    useEffect(() => {
      document.title = `新的计数: ${count}`;
    }, [count]);

    /* useEffect: 相当于生命周期钩子,当依赖数组发生变化时执行 */

进入全屏模式,退出全屏模式

……

3.\ 总是要清理副作用

为了防止内存泄漏,在组件卸载时或当效果重新运行时,清理这些副作用,比如订阅或定时器。

例子:

useEffect(() => {
  const timer = setInterval(() => {
    console.log("定时器在运行");
  }, 1000);

  return () => clearInterval(timer);
}, []);

进入全屏;退出全屏

此处省略了部分内容

4. 不要滥用useEffect

并不是所有的逻辑都适合放在useEffect里。例如,对于派生状态或简单的计算,你不需要使用useEffect

糟糕的例子。

useEffect(() => {
  // 设置全名,将名字和姓氏合并
  setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);

// 小注释:这里使用了useEffect钩子来监听firstName和lastName的变化,并在变化时更新fullName。
// setFullName是设置全名的函数,firstName表示名字,lastName表示姓氏。

全屏 退出全屏

好的例子

    const fullName = `${名字} ${姓氏}`;

点击进入全屏模式,点击退出全屏模式

……

5. 使用自定义挂钩达到可复用的效果

将重复的useEffect逻辑提取到自定义钩子里,来简化组件结构,从而促进代码的重用。

例如:

    const useFetchData = (url) => {
      const [data, setData] = useState(null);

      useEffect(() => {
        const fetchData = async () => {
          const response = await fetch(url);
          const result = await response.json();
          setData(result);
        };
        fetchData();
      }, [url]);

      // 返回数据
      return data;
    };

进入全屏,退出全屏

用法如下:

// 从"/api/data"获取数据并存储在data常量中
const data = useFetchData("/api/data");

进入全屏,退出全屏

……

useEffect 的常见坑

一. 忘记依赖项

缺失的依赖项可能会导致您的功能使用过时的值或错过必要的更新。请务必列出功能中使用的所有变量。

2. 创建无限循环(死循环)

在效果中不加适当的条件更新状态可能导致不断重复的渲染。

比如说,一个不好的例子:

    useEffect(() => {
      setCount(count + 1); // 导致计数器无限增加,从而触发无限重新渲染
    }, [count]);

点击进入全屏模式。点击退出全屏模式。

解决:

    useEffect(() => {
      // 当计数小于10时,将计数增加1
      if (count < 10) {
        setCount(count + 1);
      }
    }, [count]);

全屏。退出全屏。

……

3. 内存泄露

忘记移除诸如事件监听器或定时器之类的对象可能导致内存泄漏,尤其是在较大的应用中。

不好的例子

    useEffect(() => {
      window.addEventListener("resize", handleResize);
    }, []); // Missing cleanup

全屏模式 退出全屏

修一下:

    useEffect(() => {
      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    }, []);

全屏 退出全屏

此处省略内容

4. 效果过于复杂

避免使用useEffect来解决可以直接在渲染过程中或通过衍生状态解决的问题。


JavaScript 如何在 useEffect 中发挥作用

React 和现代 JavaScript 紧密相连。例如 async/await、解构和可选链可以让你的 useEffect 逻辑更加简洁和高效。

示例:在效果中使用async/await功能

    useEffect(() => {
      const fetchData = async () => {
        try {
          const response = await fetch("/api/data");
          const result = await response.json();
          setData(result);
        } catch (error) {
          console.error("数据获取失败:", error);
        }
      };
      fetchData();
    }, []);

全屏,退出全屏


最后

掌握好 useEffect 对构建稳健的 React 应用程序至关重要。遵循最佳实践,避免常见的陷阱和错误,并利用最新的 JavaScript 特性,你可以写出干净、可维护且高效的代码。

了解更多:现代 JavaScript 是 React 的核心。我的电子书《JavaScript:从 ES2015 到 ES2023》是一本从解构到最新 ES2023 特性的全面指南。掌握这些知识是编写高效且易于维护的 React 代码的关键。

👉 下载电子书版本 - JavaScript从ES2015到ES2023

javascript-from-es2015-to-es2023
(来自qirolab.com的JavaScript从ES2015到ES2023)
点击这里了解更多信息

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消