在我的Next.js应用程序中,我似乎无法访问窗口:
未处理的拒绝(ReferenceError):没有定义窗口
componentWillMount() {
console.log('window.innerHeight', window.innerHeight);
}
在我的Next.js应用程序中,我似乎无法访问窗口:
未处理的拒绝(ReferenceError):没有定义窗口
componentWillMount() {
console.log('window.innerHeight', window.innerHeight);
}
当前回答
如果它是NextJS应用,并且在_document.js中,使用下面的方法:
<script dangerouslySetInnerHTML={{
__html: `
var innerHeight = window.innerHeight;
`
}} />
其他回答
将代码从componentWillMount()移动到componentDidMount():
componentDidMount() {
console.log('window.innerHeight', window.innerHeight);
}
在Next.js中,componentDidMount()只在提供窗口和其他浏览器特定api的客户端上执行。来自Next.js wiki:
js是通用的,这意味着它首先在服务器端执行代码, 然后客户端。窗口对象只在客户端显示,因此if 你绝对需要在一些React组件中访问它 应该把该代码放在componentDidMount中。这个生命周期方法 只能在客户端执行。你可能还想检查一下是否有 是不是有其他的通用库可以满足你的需要。
同样,componentWillMount()将在React的v17中被弃用,因此在不久的将来使用它实际上可能是不安全的。
您可以定义一个状态变量并使用窗口事件句柄来处理这样的更改。
const [height, setHeight] = useState();
useEffect(() => {
if (!height) setHeight(window.innerHeight - 140);
window.addEventListener("resize", () => {
setHeight(window.innerHeight - 140);
});
}, []);
对于这种情况,Next.js具有动态导入功能。
对于包含只在浏览器中工作的库的模块,建议使用动态导入。请参考
对于Next.js 12.1.0版本,我发现我们可以使用process。标题,以确定我们是在浏览器中还是在节点端。希望能有所帮助!
export default function Projects(props) {
console.log({ 'process?.title': process?.title });
return (
<div></div>
);
}
1. 从终端,我接收{'进程?。标题':'节点'}
2. 从Chrome devtool,我建议{'进程?。Title: 'browser'}
如果你使用React Hooks,你可以将代码移动到Effect Hook中:
import * as React from "react";
export const MyComp = () => {
React.useEffect(() => {
// window is accessible here.
console.log("window.innerHeight", window.innerHeight);
}, []);
return (<div></div>)
}
useEffect中的代码只在客户端(在浏览器中)执行,因此它可以访问window。