防止React在hydrate时重新渲染部分SSR内容。

4

如何在React.hydrate(...)期间防止SSR内容在客户端浏览器中重新渲染?

我的工作流程

在我的当前项目中,我通过ReactDomServer.renderToString(...)在构建过程中呈现了一堆React组件。这个呈现的结果将被用作Thymeleaf片段。SSR DOM包含多个th:text属性以进行国际化:

简单示例

这是我的组件:

import React from "react";

class WdbThym extends React.Component {
    constructor(props) {
        super(props);
    }

    shouldComponentUpdate() {
        return false;
    };

    render() {
        return (
            <span {...{ 'th:text': `#{${this.props.i18n}}` }}>
                {this.props.i18n}
            </span>
        );
    }
}

export default WdbThym;

这是使用 WdbThym 的示例用法:
<WdbThym i18n="general.hello_world" />

这是ReactDomServer.renderToString(...)创建的内容:
<span th:text="#{general.hello_world}">general.hello_world</span>

这是Thymeleaf渲染并发送给客户端的内容:
<span>Hello World!</span>

这是React.hydrate渲染的内容:
<span th:text="#{general.hello_world}">general.hello_world</span>

我该如何防止上述的ComponentReact.hydrate(...)时进行初始渲染?

1
你有检查相关问题,例如 https://github.com/facebook/react/issues/8017 吗? - Estus Flask
我已经遇到过这个问题了@estus。给出的建议在我的当前项目中没有起作用。但是,我使用给出的建议创建了另一个小例子,它按照描述工作。在我的当前项目中肯定还有其他问题 :) - Sebastian Ullrich
正如@estus所报告的那样,https://github.com/facebook/react/issues/8017解决了这个问题。我创建了一个稍微复杂一些的示例来重现给出的建议:https://codesandbox.io/s/o5171l2v59 - Sebastian Ullrich
1个回答

4

正如@estus所报告的那样,https://github.com/facebook/react/issues/8017解决了这个问题。

我创建了一个稍微复杂一些的示例来重现给出的建议:

DOM

<div id="root">
  <div class="App">
    <h1>THIS IS SSR CONTENT</h1>
    <p>Current Time: 2019-01-27T08:00:00.000Z</p>
    <p>Hello World from Thymeleaf (SSR)</p>
  </div>
</div>

React

class CsrComponent extends React.Component {
  state = { currentTime: "" };

  componentDidMount = () => {
    setInterval(() => {
      this.setState({ currentTime: new Date().toISOString() });
    }, 1000);
  };

  render() {
    return <p>Current Time: {this.state.currentTime}</p>;
  }
}

class SsrComponent extends React.Component {
  render() {
    return (
      <p
        dangerouslySetInnerHTML={{ __html: "" }}
        suppressHydrationWarning
        {...{ "th:text": `#{${this.props.i18n}}` }}
      />
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <h1>THIS IS SSR CONTENT</h1>
        <CsrComponent />
        <SsrComponent i18n="general.hello_world" />
      </div>
    );
  }
}

保湿

const rootElement = document.getElementById("root");
ReactDOM.hydrate(<App />, rootElement);

这个示例也可以在https://codesandbox.io/s/o5171l2v59找到。

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