繁体   English   中英

React:关于使用 ref 和 useLayoutEffect 来确定组件是挂载还是卸载的问题

[英]React: question about using ref and useLayoutEffect to determine if a component is mounted or unmounted

我有一个这样的组件

function App() {
  const mounted = useRef()
  useLayoutEffect(() => {
    mounted.current = true
    return () => {
      console.log('unmounted') // this does not get called when I unmount the component
      mounted.current = false
    }
  }, [])

  if (mounted.current) {
    console.log('mounted')
  }
  return (
    <div>
      {/* this hello world div doesn't get rendered on the screen👇, I thought useLayoutEffect would be called before browser paints screen */}
      {mounted.current && <div>hello world</div>}
    </div>
  )
}

我知道useEffect可以达到目的。 我使用useLayoutEffect是因为它比useEffect运行得早一点。 根据这个https://github.com/donavon/hook-flow钩子流程图。

我的问题是:

  1. 卸载组件后,我没有看到console.log('unmounted')运行
  2. 我期待<div>hello world</div>在我刷新页面后呈现在屏幕上,因为我useLayoutEffect回调会在浏览器绘制屏幕之前运行,当它绘制屏幕时,ref 设置为 true通过回调。

我期待 hello world 在我刷新页面后呈现在屏幕上,因为我 useLayoutEffect 回调会在浏览器绘制屏幕之前运行,当它绘制屏幕时,ref 被回调设置为 true。

虽然useLayoutEffect比运行更快useEffect它仍然是异步的 它类似于setTimeout(fn, 0)setTimeout(fn, 60)之间的区别。 useLayoutEffect回调直到功能组件返回后才会运行,但在用户看到新元素之前运行。

因此,由于mounted.current在组件第一次渲染时为false,并且由于没有发生状态更改,因此不会重新渲染,并且不会出现hello world

卸载组件后,我没有看到 console.log('unmounted') 运行

在这里工作正常,我看到了:

 function App() { const mounted = React.useRef() React.useLayoutEffect(() => { mounted.current = true return () => { console.log('unmounted') // this does not get called when I unmount the component mounted.current = false } }, []) if (mounted.current) { console.log('mounted') } return ( <div> {/* this hello world div doesn't get rendered on the screen👇, I thought useLayoutEffect would be called before browser paints screen */} {mounted.current && <div>hello world</div>} </div> ) } const Outer = () => { const [show, setShow] = React.useState(true); React.useEffect(() => { setTimeout(() => { setShow(false); }, 2000); }, []); return ( show ? <App /> : null ); }; ReactDOM.render(<Outer />, document.querySelector('.react'));
 <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div class='react'></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM