useUpdateEffect 用法等同于 useEffect,但是会忽略首次执行,只在依赖更新时执行。

使用方式

  1. import React, { useEffect, useState } from 'react';
  2. import { useUpdateEffect } from 'ahooks';
  3. export default () => {
  4. const [count, setCount] = useState(0);
  5. const [effectCount, setEffectCount] = useState(0);
  6. const [updateEffectCount, setUpdateEffectCount] = useState(0);
  7. useEffect(() => {
  8. setEffectCount((c) => c + 1);
  9. }, [count]);
  10. useUpdateEffect(() => {
  11. setUpdateEffectCount((c) => c + 1);
  12. return () => {
  13. // do something
  14. };
  15. }, [count]); // you can include deps array if necessary
  16. return (
  17. <div>
  18. <p>effectCount: {effectCount}</p>
  19. <p>updateEffectCount: {updateEffectCount}</p>
  20. <p>
  21. <button type="button" onClick={() => setCount((c) => c + 1)}>
  22. reRender
  23. </button>
  24. </p>
  25. </div>
  26. );
  27. };

使用场景

  • 忽略首次执行,只在依赖更新时执行

具体实现

  1. export const createUpdateEffect: (hook: EffectHookType) => EffectHookType =
  2. (hook) => (effect, deps) => {
  3. const isMounted = useRef(false);
  4. // for react-refresh
  5. hook(() => {
  6. return () => {
  7. isMounted.current = false;
  8. };
  9. }, []);
  10. hook(() => {
  11. if (!isMounted.current) {
  12. isMounted.current = true;
  13. } else {
  14. return effect();
  15. }
  16. }, deps);
  17. };
  18. export default createUpdateEffect;
  1. import { useEffect } from 'react';
  2. import { createUpdateEffect } from '../createUpdateEffect';
  3. export default createUpdateEffect(useEffect);

1.useRef缓存页面是否挂载(第一次执行副作用)

2.如果挂载,则记录,记录的同时不进行任何处理

3.依赖变更后,判断是否执行过副作用,如果已经执行过,就更新

4.注意点:使用HOC方式进行逻辑复用

💡由于useEffect和useLayoutEffect作用以及Api相近,逻辑可以复用,官方使用了HOC的写法。