If you open this code in a browser and look in the developer tools under the "elements" tab, you will see that after the button is clicked, the element will be added to the DOM but will not be rendered.
How does React do it? What browser mechanism or API is being used and how?
Also, if you remove "console.log(element)" from useLaoutEffect, then the component will not immediately appear in the "elements" tab in the DOM tree. Why is this happening?
const sleep = (duration) => {
const start = new Date().getTime();
let end = start;
while(end < start + duration) {
end = new Date().getTime();
}
}
const Message = ({boxRef, children}) => {
const msgRef = React.useRef(null);
React.useLayoutEffect(() => {
const element = document.querySelector('.msg');
console.log(element);
const rect = boxRef.current.getBoundingClientRect();
sleep(1000);
msgRef.current.style.top = `${rect.height + rect.top}px`;
}, []);
return <span ref={msgRef} className="msg">{children}</span>;
};
const Index = () => {
const [show, setShow] = React.useState(false);
const boxRef = React.useRef(null);
return (
<div>
<div ref={boxRef} className="box" onClick={() => setShow(prev => !prev)}>Click me</div>
{show && <Message boxRef={boxRef}>Foo bar baz</Message>}
</div>
);
};
ReactDOM.render(<Index />, document.getElementById('root'));
.box {
position: absolute;
width: 100px;
height: 100px;
border: 1px solid green;
user-select: none;
}
.msg {
user-select: none;
position: relative;
border: 1px solid red;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>