2

官方文档中,它说,React will attempt to attach event listeners to the existing markup.
所以我认为如果我使用 ReactDOM.hydrate,它只会添加事件。

// server.js
app.get('/', (req, res) => {
    const html = fs.readFileSync(path.resolve('./build/index.html'), 'utf8');

    return res.send(
    html.replace(
      '<div id="root"></div>',
      '<div id="root">hihi</div>',
    ),
  );
}
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.hydrate(
    <App/>,
  document.getElementById('root'),
);

// App.jsx
import React from 'react';
import styled from 'styled-components';

export default () => {
  return <Title>Hi !</Title>;
};

const Title = styled.h1`
  color: blue;
`;

但是,当水合物工作时,它会删除由 SSR 创建的 DOM,并将其替换为由 CSR(反应脚本)创建的 DOM

在此处输入图像描述

为什么会这样?

4

2 回答 2

0

您呈现的服务器HTML是,

<div id="root">
    hihi
</div>

你的客户呈现HTML的是,

<div id="root">
     <h1 style="color: blue;">Hi !</h1>
</div>

首先,浏览器加载服务器HTML。然后客户端开始在服务器渲染上补水,HTML这与客户端渲染的版本有很大不同。因此,它会删除hihi文本,然后将h1元素添加到 DOM。这就是为什么您在刷新页面时看到闪烁的原因。您可以如下更改您的服务器HTML以解决您的问题。

// server.js
app.get('/', (req, res) => {
    const html = fs.readFileSync(path.resolve('./build/index.html'), 'utf8');

    return res.send(
    html.replace(
      '<div id="root"></div>',
      '<div id="root"><h1 style="color: blue;">Hi !</h1></div>',
    ),
  );
}

当你尝试做一个真正的项目时,你需要ReactDOM.renderToString在服务器端使用。有很多文章可以开始。请检查这个=> https://medium.com/bucharestjs/upgrading-a-create-react-app-project-to-a-ssr-code-splitting-setup-9da57df2040a

于 2021-04-11T10:59:14.760 回答
0

这不是 React SSR 的工作方式。您也应该在服务器端做出反应,并且可能您可以在服务器端使用 renderToString 。这样反应就会知道这是服务器渲染的反应节点,需要在客户端进行水合。

于 2020-02-27T03:11:04.347 回答