使用钩子调整大小时测量 React DOM 节点



我正在尝试测量窗口调整大小事件上的 React DOM 节点。我已经在 React 钩子常见问题解答中使用了这个示例,但它只发生在第一次渲染中。如果我添加一个useEffect来侦听调整大小,则不会调用回调?

function MeasureExample() {
const [height, setHeight] = useState(0);
const measuredRef = useCallback(node => {
if (node !== null) {
setHeight(node.getBoundingClientRect().height);
}
}, []);

// Adding this effect doesn't re-calculate the height???
useEffect(() => {
window.addEventListener("resize", measuredRef);
return (): void => {
window.removeEventListener("resize", measuredRef);
};
}, [height])
return (
<>
<h1 ref={measuredRef}>Hello, world</h1>
<h2>The above header is {Math.round(height)}px tall</h2>
</>
);
}

这是另一种解决方案。

function MeasureExample() {
const [height, setHeight] = useState(0);
const [node, setNode] = useState(null);
const measuredRef = useCallback(node => {
if (node !== null) {
setNode(node);
}
}, []);
useLayoutEffect(() => {
if(node){
const measure = () => {
setSize(node.getBoundingClientRect().height);
}

window.addEventListener("resize", measure );
return () => {
window.removeEventListener("resize", measure );
};
}
}, [node])
return (
<>
<h1 ref={measuredRef}>Hello, world</h1>
<h2>The above header is {Math.round(height)}px tall</h2>
</>
);
}

就个人而言,我会提取出侦听调整大小事件的部分。 优点是它可以再次用于其他用途。

因为调整大小是async,所以 React 的一个技巧是将子项转换为函数返回,而不仅仅是返回 JSX。 然后,您可以让 CaptureResize 组件调用该函数以获取它的 JSX,同时将大小传递给此函数。

下面是一个例子..

const {useLayoutEffect, useRef, useState} = React;
function CaptureResize(props) {
const {captureRef} = props;
function updateSize() {
setSize(captureRef.current.getBoundingClientRect());
}
useLayoutEffect(() => {
updateSize();
window.addEventListener("resize", updateSize);
return () => 
window.removeEventListener("resize", updateSize);
}, []);
const [size, setSize] = useState({});
return props.children(size)
}
function Test() {
const c = useRef(null);
return <CaptureResize captureRef={c}>
{(size) => <React.Fragment>
<h1 ref={c}>Header 1, Resize window to make this go onto diffrent no. of lines</h1>
<div>height of header = {size.height}px</div>
</React.Fragment>}
</CaptureResize>;
}
ReactDOM.render(<React.Fragment>
<Test/>
</React.Fragment>, document.querySelector('#mount'));
<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 id="mount"></div>

测量窗口屏幕大小并使用反应钩子调整大小

import React from 'react';
function useWindowDimensions() {
const [width, setWidth] = React.useState(window.innerWidth);
const [height, setHeight] = React.useState(window.innerHeight);
React.useState(() => {
const listener = () => {
setWidth(window.innerWidth)
setHeight(window.innerHeight)
}
window.addEventListener('resize', listener);
return () => {
window.removeEventListener('resize', listener);
}
})
return {
width,
height,
}
}

function App() {
const { width, height } = useWindowDimensions()
return (
<div className="App">
<h2>width: {width}</h2>
<h2>height: {height}</h2>
<p>Resize the window.</p>
</div>
)
}
export default App;

相关内容

  • 没有找到相关文章

最新更新