React SSR:服务器渲染代码中没有添加事件监听器和渲染器?
React SSR: event listeners and render are not added in server-rendered code?
我已经使用 SSR 完成了一些工作,但主要使用 NextJS -- 我理解 为什么 代码在服务器上呈现(至少首先)(以显示快速使用屏幕,以允许搜索引擎解析 SPA),并且在某种程度上 如何 它是如何完成的(服务器端的某些引擎将采用 SPA 并将其转换为 HTML 然后将其 'down' 发送到浏览器)。
我不明白的是SSR的一步步过程需要什么。我一直在学习关于中级 React 的前端硕士课程,该课程简要介绍了 Reactdomserver——我理解这个概念:将 SPA 元素转换为字符串,并将它们发送到浏览器。该课程说 'event listeners are added later' (我想一旦 React 接管),并且 render
在服务器上不可用。我相信我理解第二部分——我想 React javascript 只是在 React 启动和 运行 之前不可用——但不理解关于事件监听器的第一个语句的实际含义。当我编写老式的 HTML 代码,将其加载到服务器,然后将其下载到浏览器,加上我拥有的任何事件侦听器,它就可以正常工作。 SSR 与我们过去编写非 SPA 站点的做法有何不同?我想这是因为 DOM 在服务器上不可用,所以在浏览器中呈现 HTML 并构建 DOM 之前你不能添加事件监听器——但是因为在构建 DOM 之前不会显示任何内容,为什么还要谈论 'adding event listeners later'?
感谢您提供的任何帮助!
让我们举一个非常人为的例子 React 组件:
function App() {
const [content, setContent] = useState("click me!");
return <div onClick={() => setContent("you did it")}>{content}</div>
}
现在,在服务器上,我们要从中生成 HTML。为此,我们将 useState
模拟为 return 初始状态,调用 App(),并得到一个如下所示的 JSX 树:
{ type: "div", props: { onClick: () => ..., }, children: ["click me!"] }
现在我们可以轻松地将其转换为 HTML 的字符串 ...
<div>click me!</div>
并将其发送给客户。但是等等,onClick 有没有发生?好吧,我们无法添加它。当然,我们可以 (1) 添加一个内联 onclick 处理程序,或者 (2) 稍后注册一些事件侦听器,但是该函数是在服务器上实例化的, 不能直接序列化发送给客户端。
<script>
getElement("App").onClick(() => {
setContent("you did it!"); // Um ... Were does it refer to?
});
</script>
现在怎么办?好吧,我们可以把React Component再拿来,把它变成一段JS,打算运行整个前端。然后我们就可以把那段JS附加到我们发给客户端的HTML上了。现在我们 运行 在前端使用相同的代码,但是这次我们确实可以访问 DOM,我们可以注册处理程序,并且我们可以 rerender if setState被调用。因此 App() 被再次调用,但是来自 JSX returned ...
{ type: "div", props: { onClick: () => ..., }, children: ["click me!"] }
...我们现在可以直接生成元素,并附加处理程序:
const el = document.createElement(jsx.type);
el.addEventListener("click", jsx.onClick);
el.appendChild("click me!");
而这正是 NextJS 为您所做的。
我已经使用 SSR 完成了一些工作,但主要使用 NextJS -- 我理解 为什么 代码在服务器上呈现(至少首先)(以显示快速使用屏幕,以允许搜索引擎解析 SPA),并且在某种程度上 如何 它是如何完成的(服务器端的某些引擎将采用 SPA 并将其转换为 HTML 然后将其 'down' 发送到浏览器)。
我不明白的是SSR的一步步过程需要什么。我一直在学习关于中级 React 的前端硕士课程,该课程简要介绍了 Reactdomserver——我理解这个概念:将 SPA 元素转换为字符串,并将它们发送到浏览器。该课程说 'event listeners are added later' (我想一旦 React 接管),并且 render
在服务器上不可用。我相信我理解第二部分——我想 React javascript 只是在 React 启动和 运行 之前不可用——但不理解关于事件监听器的第一个语句的实际含义。当我编写老式的 HTML 代码,将其加载到服务器,然后将其下载到浏览器,加上我拥有的任何事件侦听器,它就可以正常工作。 SSR 与我们过去编写非 SPA 站点的做法有何不同?我想这是因为 DOM 在服务器上不可用,所以在浏览器中呈现 HTML 并构建 DOM 之前你不能添加事件监听器——但是因为在构建 DOM 之前不会显示任何内容,为什么还要谈论 'adding event listeners later'?
感谢您提供的任何帮助!
让我们举一个非常人为的例子 React 组件:
function App() {
const [content, setContent] = useState("click me!");
return <div onClick={() => setContent("you did it")}>{content}</div>
}
现在,在服务器上,我们要从中生成 HTML。为此,我们将 useState
模拟为 return 初始状态,调用 App(),并得到一个如下所示的 JSX 树:
{ type: "div", props: { onClick: () => ..., }, children: ["click me!"] }
现在我们可以轻松地将其转换为 HTML 的字符串 ...
<div>click me!</div>
并将其发送给客户。但是等等,onClick 有没有发生?好吧,我们无法添加它。当然,我们可以 (1) 添加一个内联 onclick 处理程序,或者 (2) 稍后注册一些事件侦听器,但是该函数是在服务器上实例化的, 不能直接序列化发送给客户端。
<script>
getElement("App").onClick(() => {
setContent("you did it!"); // Um ... Were does it refer to?
});
</script>
现在怎么办?好吧,我们可以把React Component再拿来,把它变成一段JS,打算运行整个前端。然后我们就可以把那段JS附加到我们发给客户端的HTML上了。现在我们 运行 在前端使用相同的代码,但是这次我们确实可以访问 DOM,我们可以注册处理程序,并且我们可以 rerender if setState被调用。因此 App() 被再次调用,但是来自 JSX returned ...
{ type: "div", props: { onClick: () => ..., }, children: ["click me!"] }
...我们现在可以直接生成元素,并附加处理程序:
const el = document.createElement(jsx.type);
el.addEventListener("click", jsx.onClick);
el.appendChild("click me!");
而这正是 NextJS 为您所做的。