[英]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钩子流程图。
我的问题是:
console.log('unmounted')
运行<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.