【问题标题】:React SSR: Prevent client side rendering of components which are rendered on the serverReact SSR:防止客户端渲染在服务器上渲染的组件
【发布时间】:2018-06-05 06:19:58
【问题描述】:

我是 React 新手。 我正在使用 react、react router4、react redux 等构建一个站点,其中很少有组件在服务器上呈现(主要是使用 API 调用获取数据并显示它们)。 现在我的问题是,如果我在服务器上渲染组件并将渲染后的 HTML 发送到客户端,它会再次在客户端上渲染(进行 API 调用),这是我需要防止的。

如果组件已经在服务器上渲染,我不想再次渲染它。我怎样才能做到这一点?

谢谢

萨蒂什

【问题讨论】:

  • 您可以随时检查 WINDOW 是否存在,并根据构造函数中布尔值的结果以及生命周期方法执行代码。此外,您可以检查是否已获取数据....
  • 感谢您的回复,但我没有得到您的句子,“您始终可以检查 WINDOW 是否存在并根据构造函数中布尔值的结果执行代码”。你能详细说明一下,这是怎么做到的?谢谢
  • 当然,所以如果您在服务器上,浏览器窗口将不可用,但如果您在客户端,浏览器窗口将可用。知道这是否已定义-您知道您是在服务器端还是在客户端。知道了这一点,你就可以告诉你的组件是否渲染。 if(typeof window == "undefined"){ return false; }
  • 好主意,会试试这个。 - 谢谢
  • 嗨,我在 'render()' 和 'componentWillMount()' 方法中尝试了相同的方法,但是这个初始页面显示了来自服务器的渲染 HTML,之后它被清除了。当我调试它时,我知道在调用组件的 createClass() 方法时,它会再次初始化整个组件,这会清除所有内容,并返回 false 语句完成执行而不渲染页面。我在这里做错了吗?

标签: reactjs react-redux react-router-v4 server-side-rendering


【解决方案1】:

我也有类似的问题。我在服务器上呈现了一个大表(5000 行)。我不想将数据发送到客户端两次(以 HTML 和 JSON 形式)我想出了这个解决方案/hack。

在渲染表格行之前,组件首先检查 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 结合起来,以防止在初始安装后出现任何渲染。

【讨论】:

  • 感谢 Safari 先生,这解决了我的愿望。有没有其他方法可以达到同样的效果?
  • @SatishLakhani 抱歉。我真的不知道其他任何事情
  • @M.R.Safari 如何使用组件的状态通过 html 标签进行渲染?
  • @SatishLakhani 还有另一种方法。您可以与服务器和客户端共享请求实现,在服务器中渲染 HTML,然后使用 serialize-javascriptwindow 中将数据作为全局状态传入。如果您的组件看到全局状态存在,它不会再次获取数据。您需要补充水分才能使其发挥作用。
【解决方案2】:

你可以使用来自 'react-dom' 的水合物

https://reactjs.org/docs/react-dom.html#hydrate

【讨论】:

  • 仅使用来自react-domhydrate 将无法实现OP 的要求
猜你喜欢
  • 2019-08-07
  • 2018-01-05
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2020-03-18
  • 1970-01-01
  • 2019-10-08
相关资源
最近更新 更多