如何在ReactJS中获得视口高度?在正常的JavaScript中使用
window.innerHeight()
但是使用ReactJS,我不确定如何获得这些信息。我的理解是
ReactDOM.findDomNode()
仅适用于已创建的组件。然而,对于文档或body元素,情况并非如此,它们可以为我提供窗口的高度。
如何在ReactJS中获得视口高度?在正常的JavaScript中使用
window.innerHeight()
但是使用ReactJS,我不确定如何获得这些信息。我的理解是
ReactDOM.findDomNode()
仅适用于已创建的组件。然而,对于文档或body元素,情况并非如此,它们可以为我提供窗口的高度。
当前回答
我建议使用useSyncExternalStore
import { useSyncExternalStore } from "react";
const store = {
size: {
height: undefined,
width: undefined
}
};
export default function ChatIndicator() {
const { height, width } = useSyncExternalStore(subscribe, getSnapshot);
return (
<h1>
{width} {height}
</h1>
);
}
function getSnapshot() {
if (
store.size.height !== window.innerHeight ||
store.size.width !== window.innerWidth
) {
store.size = { height: window.innerHeight, width: window.innerWidth };
}
return store.size;
}
function subscribe(callback) {
window.addEventListener("resize", callback);
return () => {
window.removeEventListener("resize", callback);
};
}
如果你想试试:https://codesandbox.io/s/vibrant-antonelli-5cecpm
其他回答
@foad abdollahi和@giovannipds答案的组合帮助我在Nextjs中使用useLayoutEffect自定义挂钩找到了一个解决方案。
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
}
function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions()
);
useLayoutEffect(() => {
const isWindow = typeof window !== 'undefined';
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
isWindow && window.addEventListener('resize', handleResize);
console.log(windowDimensions);
return () =>
isWindow && window.removeEventListener('resize', handleResize);
}, [windowDimensions]);
return windowDimensions;
}
我刚刚编辑了QoP当前的答案以支持SSR,并将其与Next.js (React 16.8.0+)一起使用:
/钩/ useWindowDimensions.js:
import { useState, useEffect } from 'react';
export default function useWindowDimensions() {
const hasWindow = typeof window !== 'undefined';
function getWindowDimensions() {
const width = hasWindow ? window.innerWidth : null;
const height = hasWindow ? window.innerHeight : null;
return {
width,
height,
};
}
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
if (hasWindow) {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}
}, [hasWindow]);
return windowDimensions;
}
/ yourComponent.js:
import useWindowDimensions from './hooks/useWindowDimensions';
const Component = () => {
const { height, width } = useWindowDimensions();
/* you can also use default values or alias to use only one prop: */
// const { height: windowHeight = 480 } useWindowDimensions();
return (
<div>
width: {width} ~ height: {height}
</div>
);
}
使用钩子(React 16.8.0+)
创建一个useWindowDimensions钩子。
import { useState, useEffect } from 'react';
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowDimensions;
}
之后你就可以像这样在元件中使用它了
const Component = () => {
const { height, width } = useWindowDimensions();
return (
<div>
width: {width} ~ height: {height}
</div>
);
}
工作示例
原来的答案
在React中也是一样的,你可以使用window。innerHeight来获取当前视口的高度。
正如你在这里看到的
添加这个是为了多样性和干净的方法。
此代码使用函数式方法。我已经使用onresize而不是addEventListener,如在其他答案中提到的。
import { useState, useEffect } from "react";
export default function App() {
const [size, setSize] = useState({
x: window.innerWidth,
y: window.innerHeight
});
const updateSize = () =>
setSize({
x: window.innerWidth,
y: window.innerHeight
});
useEffect(() => (window.onresize = updateSize), []);
return (
<>
<p>width is : {size.x}</p>
<p>height is : {size.y}</p>
</>
);
}
使用钩子:
使用useLayoutEffect在这里更有效:
import { useState, useLayoutEffect } from 'react';
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useLayoutEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowDimensions;
}
用法:
const { height, width } = useWindowDimensions();