React SSR:防止在服务器端渲染的组件在客户端进行渲染。

5
我是React新手。我正在使用React、React Router4、React Redux等构建网站,在其中有一些组件在服务器上进行呈现(主要是使用API调用来获取数据并展示它们)。现在我的问题是,如果我在服务器上呈现组件并将呈现的HTML发送到客户端,它会再次在客户端上呈现(发起API调用),我需要避免这种情况。
如果组件已在服务器上呈现,我不想再次呈现组件。我该如何实现这个目标?
谢谢
Satish

您可以始终检查WINDOW是否存在,并根据构造函数和生命周期方法中布尔值的结果编写代码。此外,您还可以检查数据是否已获取... - Spencer Bigum
谢谢您的回复,但我不理解您的这句话:“您可以始终检查WINDOW是否存在,并根据构造函数中布尔值的结果执行代码。” 您能否详细说明如何实现? - Satish Lakhani
当你在服务器端时,浏览器窗口是不可用的,但是当你在客户端时,浏览器窗口是可用的。如果确定了这一点,你就知道自己是在服务器端还是客户端。有了这个信息,你就可以告诉你的组件是否要渲染。 如果(typeof window == "undefined"){ return false; } - Spencer Bigum
好主意,会尝试的。- 谢谢 - Satish Lakhani
嗨,我在'render()'和'componentWillMount()'方法中尝试了相同的操作,但是初始页面显示来自服务器的渲染HTML,之后它被清除。当我调试它时,我发现在调用组件的createClass()方法时,它会重新初始化整个组件,从而清除所有内容,并且返回false语句完成执行而不呈现页面。我在这里做错了什么吗? - Satish Lakhani
我有点迷失于你最近尝试的事情 - 你能解释一下吗? - Spencer Bigum
2个回答

2
我有一个类似的问题。我有一张大表(5000行)在服务器上渲染。我不想两次将数据发送到客户端(以HTML和JSON形式)。我想到了这个解决方案/技巧。
在渲染表行之前,组件首先检查DOM,查看是否存在具有相同id的组件(如果是预先在服务器端呈现的,则存在),如果存在,则提取HTML并直接使用dangerouslySetInnerHTML
 renderTable() {
    debug('render table');
    const id = 'table-body';
    const html = this.getExistingHtml(id);

    if (html) {
      return <tbody id={ id } dangerouslySetInnerHTML={{ __html: html }} />;
    }

    return <tbody id={ id }>{ this.renderItems() }</tbody>;
  }

  getExistingHtml(id) {
    if (typeof document === 'undefined') return;
    const node = document.getElementById(id);
    return node && node.innerHTML;
  }

  renderItems() {
    debug('render items');
    return this.props.items.map(({ name, url }) => {
      return (
        <tr>
          <td>
            <a href={ url }>
              <div>{ name }</div>
            </a>
          </td>
        </tr>
      );
    });
  }

  shouldComponentUpdate() {
    return false;
  }

我还结合了shouldComponentUpdate,以防止初始挂载后的任何呈现。

谢谢M.R. Safari,这解决了我的需求。 是否有其他可能实现相同的方法? - Satish Lakhani
@SatishLakhani 抱歉,我真的不知道其他的东西。 - M.R.Safari
@M.R.Safari,你如何在使用HTML标记渲染时使用组件的状态? - Tugrul Emre Atalay
@SatishLakhani 还有另一种方法。您可以将请求实现与服务器和客户端共享,在服务器上呈现HTML,然后使用serialize-javascript将数据作为全局状态传递到window中。如果组件看到全局状态存在,则不会再次获取数据。您需要进行水合作用才能使其正常工作。 - dimiguel

-3

仅仅使用react-dom中的hydrate方法是无法实现OP所要求的功能的。 - Marcel M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接