Reputation: 1047
How can I prevent SSR content from re-rendered in the clients browser on React.hydrate(...)
?
In my current project, I render a bunch of React components during my build process via ReactDomServer.renderToString(...)
. The result of this rendering will be used as a Thymeleaf fragment. The SSR DOM contains several th:text
attributes for internalization:
This is my component:
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;
This is an example usage of WdbThym
:
<WdbThym i18n="general.hello_world" />
This is what ReactDomServer.renderToString(...)
creates:
<span th:text="#{general.hello_world}">general.hello_world</span>
This is what Thymeleaf renders and dispatches to the client:
<span>Hello World!</span>
This is what React.hydrate
renders:
<span th:text="#{general.hello_world}">general.hello_world</span>
How can I prevent the initial rendering on React.hydrate(...)
for the above mentioned Component
?
Upvotes: 4
Views: 5175
Reputation: 1047
As @estus reported, https://github.com/facebook/react/issues/8017 solved this problem.
I've created a slightly more complex sample to reproduce the given advice:
<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);
This given example is also available at https://codesandbox.io/s/o5171l2v59
Upvotes: 4