Remix 中的默认服务器端值会发生什么情况?
我正在使用以下钩子(取自在ReactJS中获取视口/窗口高度)。我已经调整了该钩子,以便可以在服务器上呈现它(通过在条件内限制对 window
的访问)。
import { useState, useEffect } from 'react';
function getWindowDimensions() {
if (typeof window !== 'undefined') {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
return { width: -1, height: -1 }
}
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;
}
我注意到一些有趣/令人困惑的事情:
- 当在服务器上呈现时,挂钩确实返回
{width: -1, height: -1}
的默认值 - 这些值似乎是由父组件观察到的。示例:
export default function FooComponent() {
const { width, height} = useWindowDimensions();
// this invariant fails
invariant(width > -1 && height > -1);
}
但是,如果我在 invariant(...)
行下方插入 console.log(width, height)
,我永远不会看到 -1, -1
在浏览器控制台中。
所以看起来 invariant
仅在服务器上触发,而 console.log
仅在客户端上运行。有人能解释一下这是怎么回事吗?即,为什么该组件不遵守默认的服务器端值?
I'm using the following hook (taken from Get viewport/window height in ReactJS). I've adapted the hook so it can be rendered on the server (by gating access to window
inside a conditional).
import { useState, useEffect } from 'react';
function getWindowDimensions() {
if (typeof window !== 'undefined') {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
return { width: -1, height: -1 }
}
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;
}
I've noticed something interesting / confusing:
- The hook does return the default values of
{width: -1, height: -1}
when it is rendered on the server - These values are seemingly observed by parent component. Example:
export default function FooComponent() {
const { width, height} = useWindowDimensions();
// this invariant fails
invariant(width > -1 && height > -1);
}
However, if I insert a console.log(width, height)
, below the invariant(...)
line, I never see -1, -1
in the browser console.
So it looks like the invariant
is only triggered on the server and console.log
is only run on the client. Can someone explain what's going on here? I.e, why does the component not observe default server side values?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它与 https://github.com/zertosh/invariant 不变吗?
自述文件中的注释指出,如果 process.env.NODE_ENV 不是 Production,即使条件为 true,它也会抛出异常。
对于只渲染客户端的组件,SergioDXA(顶级混音贡献者)提供了一个很酷的包: https://github.com/sergiodxa/remix-utils#clientonly
Is it invariant from https://github.com/zertosh/invariant ?
A note on the readme says that if
process.env.NODE_ENV
is notproduction
it'll throw even if condition is true.And for component that should only render client side, there is a cool package by SergioDXA (a top remix contributor) : https://github.com/sergiodxa/remix-utils#clientonly