【问题标题】:React SSR: event listeners and render are not added in server-rendered code?React SSR:服务器渲染代码中没有添加事件侦听器和渲染?
【发布时间】:2019-12-24 22:27:26
【问题描述】:

我已经使用 SSR 完成了一些工作,但主要使用 NextJS —— 我理解为什么代码在服务器上呈现(首先,至少)(以快速向用户显示屏幕,允许搜索引擎解析 SPA),以及在某种程度上如何完成(服务器端的某些引擎将获取 SPA 并将其转换为 HTML,然后将其“向下”发送到浏览器)。

我不明白 SSR 的逐步过程需要什么。我一直在学习关于中级 React 的前端大师课程,该课程简要介绍了 Reactdomserver——我理解这个概念:将 SPA 元素转换为字符串,并将它们发送到浏览器。该课程说“稍后添加事件侦听器”(我想一旦 React 接管),并且 render 在服务器上不可用。我相信我理解了第二部分——我想 React javascript 在 React 启动并运行之前不可用——但不明白关于事件侦听器的第一条语句的实际含义。当我编写老式的 HTML 代码,将其加载到服务器,然后将其下载到浏览器时,连同我拥有的任何事件侦听器一起完成,它就可以正常工作了。 SSR 与我们在过去编写非 SPA 网站时所做的有什么不同?我想这是因为 DOM 在服务器上不可用,所以在浏览器中呈现 HTML 并构建 DOM 之前,您不能添加事件侦听器 - 但是在构建 DOM 之前什么都不会显示,为什么甚至谈论“稍后添加事件侦听器”?

感谢您提供的任何帮助!

【问题讨论】:

    标签: javascript reactjs server-side-rendering


    【解决方案1】:

    让我们举一个非常人为的例子 React Component:

    function App() {
     const [content, setContent] = useState("click me!");
    
     return <div onClick={() => setContent("you did it")}>{content}</div>
    }
    

    现在,在服务器上,我们要从中生成 HTML。为此,我们模仿 useState 来返回初始状态,调用 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 组件,并将其变成一段 JS,旨在作为一个整体在前端运行。然后我们可以将那段 JS 附加到我们发送给客户端的 HTML 中。现在我们在前端运行相同的代码,但这次我们确实可以访问 DOM,我们可以注册处理程序,如果 setState 被调用,我们可以重新渲染。因此 App() 再次被调用,但从 JSX 返回...

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

    ...我们现在可以直接生成Elements,并附加handler:

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

    而这正是 NextJS 为您所做的。

    【讨论】:

      猜你喜欢
      • 2017-08-19
      • 2018-06-05
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 2017-11-05
      • 1970-01-01
      相关资源
      最近更新 更多