[英]React: question about using ref and useLayoutEffect to determine if a component is mounted or unmounted
I have a component like this我有一个这样的组件
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>
)
}
I know that useEffect
serves the purpose too.我知道
useEffect
可以达到目的。 I used useLayoutEffect
is because it runs a bit earlier than useEffect
.我使用
useLayoutEffect
是因为它比useEffect
运行得早一点。 According to this https://github.com/donavon/hook-flow hook flow diagram.根据这个https://github.com/donavon/hook-flow钩子流程图。
My question is:我的问题是:
console.log('unmounted')
gets runconsole.log('unmounted')
运行<div>hello world</div>
to get rendered on the screen after I refresh the page since I the useLayoutEffect
callback would run before browser paints the screen by that time when it paints the screen, the ref is set to true by the callback.<div>hello world</div>
在我刷新页面后呈现在屏幕上,因为我useLayoutEffect
回调会在浏览器绘制屏幕之前运行,当它绘制屏幕时,ref 设置为 true通过回调。I was expecting hello world to get rendered on the screen after I refresh the page since I the useLayoutEffect callback would run before browser paints the screen by that time when it paints the screen, the ref is set to true by the callback.
我期待 hello world 在我刷新页面后呈现在屏幕上,因为我 useLayoutEffect 回调会在浏览器绘制屏幕之前运行,当它绘制屏幕时,ref 被回调设置为 true。
Although useLayoutEffect
runs more quickly than useEffect
, it's still asynchronous .虽然
useLayoutEffect
比运行更快useEffect
,它仍然是异步的。 It's similar to the difference between setTimeout(fn, 0)
and setTimeout(fn, 60)
.它类似于
setTimeout(fn, 0)
和setTimeout(fn, 60)
之间的区别。 The useLayoutEffect
callback will not run until after the functional component has returned, but it will run before the user can see the new element. useLayoutEffect
回调直到功能组件返回后才会运行,但会在用户看到新元素之前运行。
So, since mounted.current
is false the first time the component renders, and since no state changes occur, it doesn't re-render, and hello world
doesn't appear.因此,由于
mounted.current
在组件第一次渲染时为false,并且由于没有发生状态更改,因此不会重新渲染,并且不会出现hello world
。
After I unmount the component, I don't see console.log('unmounted') gets run
卸载组件后,我没有看到 console.log('unmounted') 运行
Works fine here, I see it:在这里工作正常,我看到了:
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.