加载中...

常规的React项目(优化三)


合理使用useEffect,避免不必要的副作用

在 React 中,useEffect 是一个常用的钩子,用于处理副作用(例如数据获取、订阅等)。但是,如果 依赖数组 配置不当,会导致以下问题:

  1. 副作用重复执行:依赖数组过大或配置错误时,会触发不必要的副作用。
  2. 副作用未更新:遗漏依赖项时,副作用无法感知到最新的状态或属性。
  3. 性能问题:过多的无效副作用调用会浪费性能。

1. 未优化代码:依赖数组配置错误


import React, { useState, useEffect } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("React");

  // useEffect 中依赖数组遗漏
  useEffect(() => {
    console.log(`计数器更新为: ${count}`);
    // 此处未配置依赖数组,导致每次组件渲染时都会执行副作用
  });

  return (
    <div>
      <h1>计数器: {count}</h1>
      <button onClick={() => setCount(count + 1)}>增加计数</button>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="输入你的名字"
        />
    </div>
  );
};

export default Counter;

问题分析:

  1. 未配置依赖数组:
    • useEffect 在每次组件渲染时都会执行。
    • name 更新时,尽管与 count 无关,副作用仍会被触发。
  2. 性能浪费:
    • 无关的副作用被频繁调用,浪费了计算资源。

1.1 优化代码:正确配置依赖数组


import React, { useState, useEffect } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("React");

  // 仅在 count 变化时执行副作用
  useEffect(() => {
    console.log(`计数器更新为: ${count}`);
  }, [count]); // 配置依赖数组,只有 count 变化时触发

  return (
    <div>
      <h1>计数器: {count}</h1>
      <button onClick={() => setCount(count + 1)}>增加计数</button>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="输入你的名字"
        />
    </div>
  );
};

export default Counter;

优化效果:

  • 只有当 count 变化时,useEffect 才会执行副作用。
  • 不再因为 name 的更新触发无意义的副作用。

2. 依赖遗漏问题

如果依赖项遗漏,可能会导致副作用无法感知到最新的状态:


import React, { useState, useEffect } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  // 副作用中使用了最新的 count,但未声明为依赖项
  useEffect(() => {
    const timer = setInterval(() => {
      console.log(`当前计数: ${count}`); // count 始终是初始值 0
    }, 1000);

    return () => clearInterval(timer);
  }, []); // 错误:遗漏 count 依赖项

  return (
    <div>
      <h1>计数器: {count}</h1>
      <button onClick={() => setCount(count + 1)}>增加计数</button>
    </div>
  );
};

export default Counter;

2.2 修复遗漏依赖的代码


import React, { useState, useEffect } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  // 添加 count 作为依赖项
  useEffect(() => {
    const timer = setInterval(() => {
      console.log(`当前计数: ${count}`); // 正常输出最新值
    }, 1000);

    return () => clearInterval(timer);
  }, [count]); // 正确:count 变化时重新设置定时器

  return (
    <div>
      <h1>计数器: {count}</h1>
      <button onClick={() => setCount(count + 1)}>增加计数</button>
    </div>
  );
};

export default Counter;

总结:如何避免不必要的副作用

  1. 总是配置依赖数组:
    • 如果副作用依赖某些状态或属性,务必将它们添加到依赖数组中。
  2. 空依赖数组:
    • 如果副作用只需要在组件挂载和卸载时运行,使用空依赖数组 []

useEffect(() => {
  console.log("组件挂载");
  return () => console.log("组件卸载");
}, []); // 仅执行一次
  1. 注意回调函数闭包问题:
    • 在副作用中使用状态时,确保将状态加入依赖数组,避免闭包问题。
  2. 避免多余的依赖:
    • 使用 useCallbackuseMemo 缓存依赖,减少依赖数组的大小。

const memoizedCallback = useCallback(() => {
  // 缓存函数
}, [dependency]);

通过合理配置依赖数组,可以有效避免不必要的副作用执行,提高应用性能和可靠性!


文章作者: LYF
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LYF !
评论
  目录