简体   繁体   English

React SSR:事件侦听器和渲染器未添加到服务器渲染的代码中?

[英]React SSR: event listeners and render are not added in server-rendered code?

I've done some work with SSR but mainly using NextJS -- I understand why the code is being rendered (first, at least) on the server (to show the user a screen quickly, to allow search engines to parse SPAs), and to some extent how it's being done (some engine on the server side will take the SPA and convert it to HTML and then sent it 'down' to the browser).我已经用 SSR 做了一些工作,但主要是使用 NextJS——我理解为什么在服务器上呈现代码(至少首先)(以快速向用户显示屏幕,允许搜索引擎解析 SPA),以及在某种程度上它是如何完成的(服务器端的某些引擎将采用 SPA 并将其转换为 HTML,然后将其“向下”发送到浏览器)。

What I don't understand is what the step-by-step process of SSR entails.我不明白的是 SSR 的分步过程需要什么。 I've been working through a Front End Master course on intermediate React that briefly touches on Reactdomserver -- I understand the concept: convert the SPA elements to strings, and send them on to the browser.我一直在学习关于 Reactdomserver 的中级 React 前端硕士课程——我理解这个概念:将 SPA 元素转换为字符串,然后将它们发送到浏览器。 The course says that 'event listeners are added later' (I suppose once React takes over), and that render isn't available on the server.该课程说“稍后添加事件侦听器”(我想一旦 React 接管),并且该render在服务器上不可用。 I believe I understand the second part -- I suppose the React javascript just isn't available until React is up and running -- but don't understand what the first statement regarding event listeners actually means.我相信我理解第二部分——我想 React javascript 在 React 启动并运行之前不可用——但不明白关于事件侦听器的第一条语句实际上意味着什么。 When I wrote old-school HTML code, loaded it to a server, and it was downloaded to a browser, complete with whatever event listeners I had, and it just worked.当我编写老式 HTML 代码时,将其加载到服务器,然后下载到浏览器,以及我拥有的任何事件侦听器,然后就可以正常工作了。 What is SSR doing differently than we did in the old days writing non-SPA sites? SSR 的做法与我们过去编写非 SPA 网站时的做法有何不同? I suppose it's that the DOM isn't available on the server, so you can't add event listeners until the HTML is rendered in the browser and the DOM is built -- but as nothing is displayed until the DOM is built, why even talk about 'adding event listeners later'?我想是因为 DOM 在服务器上不可用,所以在浏览器中呈现 HTML 并构建 DOM 之前,您无法添加事件侦听器——但是因为在构建 DOM 之前没有显示任何内容,为什么还要谈论“稍后添加事件侦听器”?

Thanks for any help you can provide!感谢您的任何帮助,您可以提供!

Let's take a very contrived example React Component:让我们举一个非常人为的例子 React 组件:

function App() {
 const [content, setContent] = useState("click me!");

 return <div onClick={() => setContent("you did it")}>{content}</div>
}

Now, on the server, we want to generate HTML from it.现在,在服务器上,我们想从中生成 HTML。 For that, we mimic useState to return the initial state, call App(), and arrive at a JSX tree that looks like:为此,我们模仿useState来返回初始状态,调用 App(),然后得到一个 JSX 树,如下所示:

{ type: "div", props: { onClick: () => ..., }, children: ["click me!"] }

Now we can turn that into a string of HTML easily ...现在我们可以轻松地将其转换为一串 HTML ......

<div>click me!</div>

and send that to the client.并将其发送给客户端。 But wait, were did the onClick go?但是等等,onClick 去了吗? Well, we could not add it.好吧,我们无法添加它。 For sure we could (1) add an inline onclick handler, or (2) register some event listener later, but the function was instantiated on the server , we can't just serialize it and send it to the client.当然,我们可以 (1) 添加内联 onclick 处理程序,或 (2) 稍后注册一些事件侦听器,该函数是在服务器上实例化,我们不能只是将其序列化并将其发送到客户端。

<script> 
  getElement("App").onClick(() => {
    setContent("you did it!"); // Um ... Were does it refer to?
  });
</script>

Now what to do?现在该怎么办? Well, we could take the React Component again, and turn it into a piece of JS, that is intended to run on the frontend as a whole .好吧,我们可以再次使用 React 组件,并将其变成一块 JS,旨在作为一个整体在前端运行 Then we can attach that piece of JS to the HTML we sent to the client.然后我们可以将那段 JS 附加到我们发送给客户端的 HTML 中。 Now we run the same code on the frontend, but this time we do have access to the DOM, we can register handlers, and we can rerender if setState gets called.现在我们在前端运行相同的代码,但这次我们可以访问 DOM,我们可以注册处理程序,如果 setState 被调用,我们可以重新渲染 Therefore App() gets called again, but from the JSX returned ...因此 App() 再次被调用,但从 JSX 返回......

 { type: "div", props: { onClick: () => ..., }, children: ["click me!"] }

... we can directly generate Elements now, and attach the handler: ...我们现在可以直接生成元素,并附加处理程序:

const el = document.createElement(jsx.type);
el.addEventListener("click", jsx.onClick);
el.appendChild("click me!");

And all that is exactly what NextJS does for you.而这一切正是 NextJS 为您所做的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 修复服务器呈现的HTML中的引号 - Fix quotes in server-rendered html 如何在反应渲染中使用事件侦听器? - How to use event listeners inside react render? Nextjs 错误:文本内容与服务器呈现的 HTML 不匹配 - Nextjs Error: Text content does not match server-rendered HTML 错误:文本内容与服务器呈现的 HTML 不匹配 - Error: Text content does not match server-rendered HTML 一旦React卸载它们,事件监听器就不会再添加的问题 - Problem with event listeners not being added again, once React unmounts them Vuejs 错误:客户端呈现的虚拟 DOM 树与服务器呈现的不匹配 - Vuejs Error: The client-side rendered virtual DOM tree is not matching server-rendered 使用 useEffect 反应事件监听器 - React event listeners with useEffect v-for 抛出呈现的 AsyncData/fetch 中的数组列表:客户端呈现的虚拟 DOM 树与服务器呈现的不匹配 - Array list from AsyncData/fetch rendered by v-for throw: The client-side rendered virtual DOM tree is not matching server-rendered NUXT - SSR - 组件未在服务器端呈现 - NUXT - SSR - components are not being rendered server side 为什么在Meteor的服务器渲染模板中将日期提前一天进行解释? - Why dates are being interpreted one day prior in server-rendered templates in Meteor?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM