如何在初始服务器端渲染后立即使用 React + NextJS 重新渲染客户端?
How to immediately re-render client-side using React + NextJS after initial server-side render?
我使用 Next.js 和 React 创建了一个网站,非常喜欢声明一个 js 变量来定义组件样式,如下所示:
const foo = {
fontSize: '12px',
};
在我的渲染方法中:
render() {
return (
<div style={foo}>bar</div>
);
}
使用 ESLint 我可以快速找到未使用的 styles/variables(如果引用不存在)并保持代码整洁。因此我 而不是 使用 <style>
或 styled-jsx 像这样:
render() {
return (
<div>
<style>
.foo {
font-size: '12px';
}
</style>
<div className="foo">bar</div>
</div>
);
}
问题
仅使用 js 变量而不是 <style>
的问题是我无法应用媒体查询来针对不同的屏幕尺寸,所以我想我可以使用 javascript:[=21= 来解决这个问题]
render() {
// Bigger font size for smaller devices
if (windowWidth < 768) foo.fontSize = '24px';
return (
<div style={foo}>bar</div>
);
}
我通过此变通方法获得 windowWidth
:。只要渲染发生在客户端,这就可以很好地工作。这种方法的问题是 Next.js 将首先在服务器端呈现视图。目前,window/screen 大小未知,因此 windowWidth = 0
。因此,我认为客户端必须在从服务器接收到初始渲染页面后重新渲染。
问题:
如何强制客户端在服务器初始渲染后立即重新渲染以确定 windowWidth
的值?
这会是一个好的 practice/solution 还是会导致性能问题或元素闪烁?
在 reactjs 中随时触发渲染的最佳方法是使用 属性 创建反应元素。在您的情况下,我会先计算要使用的字体大小,然后使用 属性.
创建元素
字体大小似乎不会改变,但如果改变了,您可能必须将此状态放在使用它的元素的公共 parent 元素中。这个 parent 将接受这个状态并将其作为其 children 的道具。
正如一位评论者所建议的那样,有一些方法可以触发更新,但最好重新组织您的元素以通过正常的 React 方法来执行此操作。不要害怕制作更多更小的 React 元素!
找到解决方法。 NextJS 将在完成服务器端渲染后自动重新渲染客户端。添加一些控制台输出显示:
const foo = {
fontSize: '12px',
};
渲染方法:
render() {
if (windowWidth < 768) {
foo.fontSize = '24px';
console.log('24px');
} else {
console.log('12px');
}
return (
<div style={foo}>bar</div>
);
}
在小屏幕上查看,这将打印:
12px
24px
然而,按下浏览器的重新加载按钮,字体大小没有改变,尽管样式变量的值明显改变了。
解决方案是创建原始对象的副本并对其进行操作:
render() {
let foo2;
if (windowWidth < 768) {
foo2 = Object.assign({}, foo, { fontSize: '24px' });
} else {
foo2 = Object.assign({}, foo);
}
return (
<div style={foo2}>bar</div>
);
}
这将在运行时更改字体大小。但是,当页面加载时,您会在几分之一秒内看到旧的 12px 字体大小,而当客户端渲染完成时,它将跳转到新的 24px 字体大小。不确定我是否会从用户体验的角度来看这个,但从技术上讲这是一个可行的解决方案。虽然不太喜欢它:-(
我使用 Next.js 和 React 创建了一个网站,非常喜欢声明一个 js 变量来定义组件样式,如下所示:
const foo = {
fontSize: '12px',
};
在我的渲染方法中:
render() {
return (
<div style={foo}>bar</div>
);
}
使用 ESLint 我可以快速找到未使用的 styles/variables(如果引用不存在)并保持代码整洁。因此我 而不是 使用 <style>
或 styled-jsx 像这样:
render() {
return (
<div>
<style>
.foo {
font-size: '12px';
}
</style>
<div className="foo">bar</div>
</div>
);
}
问题
仅使用 js 变量而不是 <style>
的问题是我无法应用媒体查询来针对不同的屏幕尺寸,所以我想我可以使用 javascript:[=21= 来解决这个问题]
render() {
// Bigger font size for smaller devices
if (windowWidth < 768) foo.fontSize = '24px';
return (
<div style={foo}>bar</div>
);
}
我通过此变通方法获得 windowWidth
:windowWidth = 0
。因此,我认为客户端必须在从服务器接收到初始渲染页面后重新渲染。
问题:
如何强制客户端在服务器初始渲染后立即重新渲染以确定
windowWidth
的值?这会是一个好的 practice/solution 还是会导致性能问题或元素闪烁?
在 reactjs 中随时触发渲染的最佳方法是使用 属性 创建反应元素。在您的情况下,我会先计算要使用的字体大小,然后使用 属性.
创建元素
字体大小似乎不会改变,但如果改变了,您可能必须将此状态放在使用它的元素的公共 parent 元素中。这个 parent 将接受这个状态并将其作为其 children 的道具。
正如一位评论者所建议的那样,有一些方法可以触发更新,但最好重新组织您的元素以通过正常的 React 方法来执行此操作。不要害怕制作更多更小的 React 元素!
找到解决方法。 NextJS 将在完成服务器端渲染后自动重新渲染客户端。添加一些控制台输出显示:
const foo = {
fontSize: '12px',
};
渲染方法:
render() {
if (windowWidth < 768) {
foo.fontSize = '24px';
console.log('24px');
} else {
console.log('12px');
}
return (
<div style={foo}>bar</div>
);
}
在小屏幕上查看,这将打印:
12px
24px
然而,按下浏览器的重新加载按钮,字体大小没有改变,尽管样式变量的值明显改变了。
解决方案是创建原始对象的副本并对其进行操作:
render() {
let foo2;
if (windowWidth < 768) {
foo2 = Object.assign({}, foo, { fontSize: '24px' });
} else {
foo2 = Object.assign({}, foo);
}
return (
<div style={foo2}>bar</div>
);
}
这将在运行时更改字体大小。但是,当页面加载时,您会在几分之一秒内看到旧的 12px 字体大小,而当客户端渲染完成时,它将跳转到新的 24px 字体大小。不确定我是否会从用户体验的角度来看这个,但从技术上讲这是一个可行的解决方案。虽然不太喜欢它:-(