如何正确编写一个自定义的依赖值的react钩子?

问题描述 投票:1回答:1

我的钩子的目标是确定菜单的 "打开方向".当没有足够的高度时,打开方向将从 "底部 "切换到 "顶部".我简化了我的代码到一个虚拟的例子,以便能够演示它.你可以在我添加的动画gif中看到它。

那么,我的问题是什么呢?在我真正的代码中,"打开方向 "的逻辑是什么?要看 在状态的最后一个 "openDirection "上,使用我习惯的类,它工作得很好,我已经添加了使用类的代码示例。handleResize 我正在向控制台写入当前的 openDirection以模拟在我的真实代码中使用它。

但是 在我的钩子代码示例中,你可以看到每次我从 handleResizeజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ openDirection 始终是状态的第一个初始值 这是底部。

我想它是这样的,因为我给了这个 [] 依赖性,所以 useLayoutEffect 只在第一次时有效。但我应该怎么做?openDirection 作为依赖关系,它将会工作,但这意味着每一次 addEventListener 将增加和 removeEventListener 将会被删除,每次调整大小的事件!

我真的很困惑,我该怎么办?

import { useLayoutEffect, useState } from 'react';

const useOpenDirection = () => {
  const [openDirection, setOpenDirection] = useState("bottom");

  useLayoutEffect(() => {
    const handleResize = () => {
      console.log('openDirection', openDirection);
      if (window.innerHeight < 622) {
        setOpenDirection("top");
      } else {
        setOpenDirection("bottom");
      }
    }

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

  return openDirection;
};

export default useOpenDirection;

实时编辑的完整代码。

类代码示例

钩子代码示例

enter image description here

javascript reactjs react-hooks window-resize
1个回答
1
投票

你的 openDirection 由于依赖的是空数组,所以已经成为一个陈旧的闭包。你可以访问当前的 openDirection 如果您使用功能更新。

useLayoutEffect(() => {
    const handleResize = () => {

        setOpenDirection(current => {
            // If you need you can also use current to compute return value of this function
            if (window.innerHeight < 622) {
                console.log('openDirection', current);
                return "top";
            } else {
                console.log('openDirection', current);
                return "bottom";
            }

        });

    }

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
}, []);
© www.soinside.com 2019 - 2024. All rights reserved.