首页 > 解决方案 > 如何使用 React Hooks 将状态值传递给回调函数

问题描述

我正在使用react-modal创建一个面板,一切似乎都运行良好。

但是一旦打开模态,我需要设置我的模态的最高值。我正在使用钩子,每当尝试更新值时,遇到错误时,只能在 React 函数内部调用钩子。我尝试了所有可能的方法,但无法解决问题。

期望: - OnAfterOpen 应该被调用,并且最新的状态值应该被传递给pos prop.

这是我尝试过的。

function useTop() {
  const [top, setTop] = useState('100px');

  useEffect(() => {
    const handleResize = () => {
      const hasRefClientHeight = contentRef.current && contentRef.current.clientHeight;
      hasRefClientHeight < window.innerHeight ? setTop(`calc(100% - ${hasRefClientHeight}px)`) : setTop('100px');
    };
    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return top;
}

const Panel = () => {
   // const newTop = useTop(); -- This is not working as modal content is not ready. Modal Content will be ready only if `onAfterOpen` triggers.

   <Modal pos={useTop} onAfterOpen={useTop}><div ref={contentRef}>Test</div></Modal>
};

标签: javascriptreactjsreact-hooks

解决方案


事实上,钩子的规则说:

https://reactjs.org/docs/hooks-rules.html

仅在顶层调用 Hooks

不要在循环、条件或嵌套函数中调用 Hook。相反,请始终在 React 函数的顶层使用 Hooks。通过遵循此规则,您可以确保每次渲染组件时都以相同的顺序调用 Hook。这就是允许 React 在多个 useState 和 useEffect 调用之间正确保留 Hooks 状态的原因。(如果您好奇,我们将在下面深入解释。)

这对于 React 来说是必要的,以确保在每个渲染周期中都会以完全相同的顺序调用钩子。

似乎只有在安装(打开)后Modal才会调用useTop,即它可能会跳过第一次渲染,违反钩子规则并弄乱顺序。

您可以尝试一件事:

通过ref你的useTop钩子并在里面处理它。如果为null,则不执行任何操作,如果已挂载,则附加侦听器并返回清理函数。

const Panel = () => {
  const newTop = useTop(contentRef);
  <Modal pos={newTop} onAfterOpen={null}><div ref={contentRef}>Test</div></Modal>
};

推荐阅读