.renderToString() &-.hydrate()

After loading the server-rendered HTML for a node, the client should 'hydrate' the node to preserve it and only attach event handlers to the node (ReactDOM.hydrate() works like ReactDOM.render()).


RESETRUNFULL
// MyProject/public/components/App.jsimport React from "react";function Greetings(props){
    return (<h2>{props.msg}</h2>);}function App(props) {
  return (<Greetings msg={props.msg}/>);}export default App;

// MyProject/public/home.jsimport React from "react";import ReactDOM from "react-dom";import App from "./components/App";ReactDOM.hydrate(
  <App msg="hi" />,
  document.getElementById("root"));

// MyProject/server.jsimport express from "express";import React from "react";import ReactDOMServer from "react-dom/server";import App from "./public/components/App.js";var app = express();app.use(express.static("./dist/public"));app.get('/', (req,res)=>{
   const component = ReactDOMServer.renderToString(<App msg="hi" />);
   const html = `
   <!DOCTYPE html><html>
     <head></head>
     <body>
        <div id="root">${component}</div>
        <script src="/home.js" type="module"></script>
      </body>
   </html>`;
   res.send(html);}); app.listen(4000);console.log('Running an Express server at http://localhost:4000/');

If you inspect the DOM on the Developer's Tools Interface (F12), you will find additional attributes (such as 'data'-reactroot') attached to the nodes.

If you want to do away with such attributes that React use internally, useReactDOMServer.renderTo StaticMarkup() instead of

ReactDOMServer.renderToString() when rendering the markup on the server side.