【问题标题】:How to immediately re-render client-side using React + NextJS after initial server-side render?如何在初始服务器端渲染后立即使用 React + NextJS 重新渲染客户端?
【发布时间】:2018-05-22 18:53:42
【问题描述】:

我使用带有 React 的 Next.js 创建了一个网站,并且非常喜欢声明一个 js 变量来定义组件样式,如下所示:

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

在渲染方法中我这样做:

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

使用 ESLint,我可以快速找到未使用的样式/变量(如果没有引用)并保持代码整洁。因此我像这样使用&lt;style&gt;styled-jsx

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

问题

仅使用 js 变量而不是 &lt;style&gt; 的问题是我无法将媒体查询应用于不同的屏幕尺寸,所以我想我可以使用 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。因此,我认为客户端在从服务器接收到初始渲染的页面后必须重新渲染。

问题:

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

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

【问题讨论】:

  • 您是否考虑过在您的顶级组件中使用forceUpdate?但是,我认为您会遇到 2.) 中列出的两个问题。取决于您编写样式的方式...如果它是移动优先的,它们会闪烁,并且可能会在桌面上触发布局重绘,反之亦然,桌面优先。跨度>
  • 您可以尝试在页面上隐藏响应元素并仅在更新后显示。
  • 你使用过componentWillMount生命周期吗??它应该工作

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


【解决方案1】:

找到了解决方案。 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 字体大小。不确定我是否会从用户体验的角度来解决这个问题,但从技术上讲,这是一个可行的解决方案。不过不是很喜欢:-(

【讨论】:

    【解决方案2】:

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

    正如评论者所说,有一些方法可以触发更新,但最好通过正常的反应方法重新组织你的元素来做到这一点。不要害怕制作更多更小的反应元素!

    【讨论】:

      猜你喜欢
      • 2018-01-05
      • 2019-08-07
      • 2015-05-07
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-17
      相关资源
      最近更新 更多