最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React 同构

    正文概述 掘金(Camol)   2021-06-22   403

    这是我参与更文挑战的第18天,活动详情查看: 更文挑战。

    前言

    React 同构,需要实现以下功能:

    • 在服务端根据 React 组件生成 html
    • 数据脱水和注水
    • 服务器端管理Redux Store
    • 支持服务器和浏览器获取共同数据源

    React服务器端渲染HTML

    React在服务器端渲染使用函数和浏览器端不一样:

    import ReactDOMServer from "react-dom/server';
    
    const appHtml = ReactDOMServer.renderToString(<RootComponent />)
    

    renderToString 函数的返回结果就是一个HTML字符串,至于这个字符串如何处理,要由开发者来决定。

    当然,只是把 renderToString 返回的字符串在浏览器中渲染出来,用户看到的只是纯静态的 HTML 而已,并不具有任何动态的交互功能。要让渲染的HTML“活”起来,还需要浏览器端执行 JavaScript 代码。

    服务器端渲染产生的React组件HTML被下载到浏览器网页之中,浏览器网页需要使用render函数重新渲染一遍React组件。

    如果服务器端渲染和浏览器端渲染产生的内容不一样,用户会先看到服务器端渲染的内容,随后浏览器端渲染会重新渲染内容,用户就会看到一次闪烁,这样给用户的体验很不好。

    为了让两端数据一致,就要涉及 脱水注水 的概念。

    脱水和注水

    服务器端渲染产出了HTML,但是在交给浏览器的网页中不光要有HTML,还需要有 脱水数据,也就是在服务器渲染过程中给React组件的输入数据,这样,当浏览器端渲染时,可以直接根据“脱水数据”来渲染React组件,这个过程叫做 注水

    脱水数据的传递方式一般是在网页中内嵌一段 JavaScript,内容就是把传递给React组件的数据赋值给某个变量,这样浏览器就可以直接通过这个变量获取脱水数据。

    需要注意的是,使用脱水数据要防止跨站脚本攻击(XSSAttack),因为脱水数据有可能包含用户输入的成分,而用户的输入谁也保不准包含什么。

    服务器端Redux Store

    在服务器端使用Redux,必须要对每个请求都创造一个新的Store,这是和浏览器渲染的最大区别。

    支持服务器和浏览器获取共同数据源

    很明显,最简单的方法,就是有一个API服务器提供接口让服务器和浏览器都能够访问,这样无论是什么样的场景,服务器和浏览器获得数据都是一致的。

    服务器端路由

    因为浏览器端使用了 React-Router 作为路由,没有理由不在服务器端使用一致的方法,不过在服务器端使用React-Router 的方式和浏览器端不一样,在浏览器端,整个 Router 作为一个 React 组件传递一个 ReactDOM的 render 函数,Router 可以自动和URL同步,但是对于服务器端的过程,URL对应到路由规则的过程需要用 match 函数:

    import { match, RouterContext } from "react-router";
    
    match({routes: routes, location: requestUrl }, function(err, redirect, renderProps){
    
        if (err) {
            return res.status(500).send(err.message);
        }
        if (redirect) {
            return res.redirect(redirect.pathname + redirect.search);
        }
        if (!renderProps) {
            return res.status(404).send("Not Found");
        }
        
        const appHtml = ReactDOMServer.renderToString(<RouterContext {...renderProps} />);
    });
    

    match 函数接受一个对象和一个回调函数作为参数,对象参数中的 routes 就是 Route 构成的路由规则树,这里根本用不上 Router 类,所以也用不上 Router 的 history 属性,这就是和浏览器端渲染的最大区别。match是通过对象参数中的 location 字段来确定路径的,不是靠和浏览器地址栏关联的 history。

    当 match 函数根据 location 和 routes 匹配完成之后,就会调用第二个回调函数参数,根据回调函数第一个参数err和第二个参数 redirect 可以判断匹配是否错误或者是一个重定向。一切顺利的话,第一第二个参数都是空,有用的就是第三个参数 renderProps,这个 renderProps 包含路由的所有信息,把它用扩展操作符展开作为属性传递给 RouterContext 组件,渲染的结果就是服务器端渲染产生的HTML字符串。


    起源地下载网 » React 同构

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元