为啥我的变量在 useEffect 中定义的其他地方在反应中未定义?

Posted

技术标签:

【中文标题】为啥我的变量在 useEffect 中定义的其他地方在反应中未定义?【英文标题】:Why is my variable defined in useEffect elsewhere undefined in react?为什么我的变量在 useEffect 中定义的其他地方在反应中未定义? 【发布时间】:2021-09-30 03:38:59 【问题描述】:

我尝试在我的 react 应用中实现来自 materializecss 的模式:

const ModalCardMetrics = (props) => 
    let modalInstance;
    let modalBox = useRef();

  useEffect(()=>
        modalInstance = window.M.Modal.init(modalBox.current, )[0];
   ,[])

 const openModal = ()=>
        modalInstance.open();  // modalInstance is undefined?!
 
 return (
        <div>
          <div rel=modalBox>...modalbox...</div>
          <button onClick=openModal>Menu</button>
        </div>
   )

未捕获的类型错误:modalInstance 未定义 toggleModal ModalCardMetrics.js:90 反应 14

在此代码框中,您会看到我的方法可行 - 我假设:我正在使用 cdn(在 index.html 中)加载 Materializecss,并且在代码框中它是通过 npm 包和导入完成的。 https://codesandbox.io/s/quiet-platform-ph8g6

【问题讨论】:

这能回答你的问题吗? Updating a JSX Variable with useEffect "lost after each rerender" Issue @pilchard 部分;因为我仍然不知道如何访问modalInstance。什么是正确的方法? - 如果它重新渲染,则将再次调用 useEffect,然后应该再次设置 modalInstance 而不是未定义? 您已将一个空的依赖数组传递给 useEffect,导致它仅在第一次渲染时运行,此时它为 modalInstance 赋值。在下一次渲染中,变量被重新声明并且 useEffect 不再运行。要跨渲染保持值,您需要实现状态或引用值。阅读文档,然后回来询问更多。 React: State and Lifecyle 我已经读过了。我仍然不明白什么时候可以访问 dom。在我使用类组件之前,我使用了 componentDidMount(); - 我也已经尝试过解决这个问题 which const [modalInstance, setModalInstance] = useState();但是,我什么时候访问 DOM 并使用 setModalInstance() 设置我的 modalInstance? useEffect 运行时,DOM 是可用的(一旦你修正了你的错字,你的 ref 将持有对相关元素的引用)。通过传递一个空的依赖数组,您的useEffect 正在实现componentDidMount() 的功能,因为它不会在连续渲染上运行。你可能想看看react-materialize 【参考方案1】:

这是一个工作沙盒,有点: https://codesandbox.io/s/immutable-sea-bvuw4?file=/src/Modal.js

您需要更改rel=modalBox

<div rel=modalBox>...modalbox...</div>

<div ref=modalBox>...modalbox...</div>

【讨论】:

请检查您的帖子。这是您的修改版本:codesandbox.io/s/quiet-platform-ph8g6【参考方案2】:

你需要在函数式反应中使用 useState

const ModalCardMetrics = (props) => 
    const [modalInstance, setModalInstance] = useState();
    let modalBox = useRef();

    useEffect(()=>
        setModalInstance(window.M.Modal.init(modalBox.current, )[0]);
     ,[])

   const openModal = ()=>modalInstance.open();
   return (
        <div>
          <div rel=modalBox>...modalbox...</div>
          <button onClick=openModal>Menu</button>
        </div>
   )

另外,别忘了导入 useState import useState from 'react'

【讨论】:

是的,这是我帖子下评论部分的结论。谢谢,这行得通!

以上是关于为啥我的变量在 useEffect 中定义的其他地方在反应中未定义?的主要内容,如果未能解决你的问题,请参考以下文章

状态在 useEffect 中没有更新,为啥?

为啥我不能从其他类访问公共变量?

为啥我的线程函数中的局部变量会被其他线程中断?

为啥从 React 的 useEffect 依赖列表中省略函数是不安全的?

为啥我的组件在使用 React 的 Context API 和 useEffect 挂钩时会渲染两次?

为啥 PanResponder 不能使用 useEffect Hook?