如何在初始服务器端呈现后立即使用React + NextJS重新呈现客户端?

时间:2017-12-08 13:58:25

标签: css reactjs responsive-design media-queries next.js

我使用React创建了一个使用Next.js的网站,并且非常想声明一个js变量来定义这样的组件样式:

const foo = {
  fontSize: '12px',
};

在渲染方法中我做了:

render() {
  return (
    <div style={foo}>bar</div>
  );
}

使用ESLint我可以快速找到未使用的样式/变量(如果引用已经消失)并保持代码清洁。因此我 使用<style>styled-jsx这样:

render() {
  return (
    <div>
      <style>
        .foo {
          font-size: '12px';
        }
      </style>
      <div className="foo">bar</div>
    </div>
  );
}

问题

仅使用js变量而不是<style>的问题是我无法应用媒体查询来定位不同的屏幕尺寸,所以我想我可以使用javascript解决这个问题:

render() {
  // Bigger font size for smaller devices
  if (windowWidth < 768) foo.fontSize = '24px';

  return (
    <div style={foo}>bar</div>
  );
}

我通过此解决方法获得windowWidthGet viewport/window height in ReactJS。只要在客户端上进行渲染,这种方法就可以正常工作。这种方法的问题是Next.js将首先在服务器端呈现视图。此时,窗口/屏幕大小未知,因此windowWidth = 0。因此,我认为客户端必须在从服务器接收到初始呈现页面后重新呈现。

问题(S):

  1. 如何在服务器初始渲染后强制客户端立即重新渲染,以确定windowWidth的值?

  2. 这是一个很好的做法/解决方案,还是会导致性能问题或元素闪烁?

2 个答案:

答案 0 :(得分:0)

在reactjs中随时触发渲染的最佳方法是使用该属性创建react元素。在您的情况下,我将计算首先使用的字体大小,然后创建具有该属性的元素 字体大小似乎不会改变,但如果确实如此,您可能必须将此状态放在使用它的元素的公共父元素中。这个父母将采取这种状态,并将其作为其子女的道具。

作为一名评论者建议有触发更新的方法,但最好通过常规的反应方法重新组织元素。不要害怕制造更小的反应元素!

答案 1 :(得分:0)

找到解决方案。在进行服务器端渲染之后,NextJS将自动重新呈现客户端。添加一些控制台输出显示:

phpinfo()

渲染方法:

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

这将在运行时更改字体大小。但是,当页面加载时,您将看到旧的12px字体大小的小数秒,当客户端渲染完成时,它将跳转到24px的新字体大小。不确定我是否会从用户体验的角度来看这个,但从技术上讲,这是一个有效的解决方案。不过不喜欢它: - (