Предотвратить React от повторного рендеринга частичного содержания SSR на гидрат - PullRequest
0 голосов
/ 26 января 2019

Как я могу предотвратить повторное рендеринг содержимого SSR в браузере клиента на React.hydrate(...)?

Мой рабочий процесс

В моем текущем проекте я рендерил несколько компонентов React во время моегопроцесс сборки через ReactDomServer.renderToString(...).Результат этого рендеринга будет использоваться как фрагмент Thymeleaf.DOM SSR содержит несколько атрибутов 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>

Как я могу предотвратить начальный рендеринг на React.hydrate(...) для вышеупомянутого Component?

1 Ответ

0 голосов
/ 01 февраля 2019

Как сообщил @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>

Реакция

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

...