今天,我们要讲解的是react+redux服务端渲染。个人认为,react击败angular的真正“杀手锏”就是服务端渲染。我们为什么要实现服务端渲染,主要是为了SEO。

例子

例子仍然是官方的计数器例子,不过我们实现了服务端渲染和state预加载。

源代码:

https://github.com/lewis617/react-redux-tutorial/tree/master/redux-examples/universal

虚拟API

首先,我们要模拟一个api,用于异步请求数据。代码如下:

common/api/counter.js

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min
}

export function fetchCounter(callback) {
  // Rather than immediately returning, we delay our code with a timeout to simulate asynchronous behavior
  setTimeout(() => {
    callback(getRandomInt(1, 100))
  }, 500)

  // In the case of a real world API call, you'll normally run into a Promise like this:
  // API.getUser().then(user => callback(user))
}

服务端请求api,发送html串和state

server/server.js(部分代码)

// This is fired every time the server side receives a request
app.use(handleRender)

function handleRender(req, res) {
  // Query our mock API asynchronously
  fetchCounter(apiResult => {
    // Read the counter from the request, if provided
    const params = qs.parse(req.query)
    const counter = parseInt(params.counter, 10) || apiResult || 0

    // Compile an initial state
    const initialState = { counter }

    // Create a new Redux store instance
    const store = configureStore(initialState)

    // Render the component to a string
    const html = renderToString(
      <Provider store={store}>
        <App />
      </Provider>
    )

    // Grab the initial state from our Redux store
    const finalState = store.getState()

    // Send the rendered page back to the client
    res.send(renderFullPage(html, finalState))
  })
}

function renderFullPage(html, initialState) {
  return `
    <!doctype html>
    <html>
      <head>
        <title>Redux Universal Example</title>
      </head>
      <body>
        <div id="app">${html}</div>
        <script>
          window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}
        </script>
        <script src="/static/bundle.js"></script>
      </body>
    </html>
    `
}
  1. api写好了,我们调用了这个api,即fetchCounter,这个api函数也会产生一个回调,我们在回调中获取counter值
  2. 如果中间件请求中有参数,则const params = qs.parse(req.query),counter为parseInt(params.counter, 10)。否则counter为api的回调中返回的值apiResult,如果前两个都没有则为0。qs用于解析http请求中的querystring,就是?param=sth。
  3. 得到counter,我们就得到了state,用state作为参数,重新生成一个store实例,每次都要重新生成一个新的store实例。然后用react的服务端渲染生成一个html串,把它发送出去
  4. 同时,我们还要发送一个const finalState = store.getState()出去,让客户端拿到这个state渲染,为什么?因为要保证客户端和服务端渲染的组件一样。

服务端渲染

既然有了服务端渲染,为何还要用客户端渲染,因为服务端渲染渲染完,我们的程序就不会动了(因为是一堆字符串),客户端则可以让程序继续动起来,因为客户端有js,可以调用方法重绘浏览器界面。

客户端拿到state再渲染一次

既然要再渲染一次,为何还要服务端渲染?为了seo,我们的服务端渲染不只是给用户看的,主要是给那些“低能”的网络爬虫看的。

好吧,忍忍火,我们继续工作,客户端再渲染一次。

const initialState = window.__INITIAL_STATE__
const store = configureStore(initialState)
const rootElement = document.getElementById('app')

render(
  <Provider store={store}>
    <App/>
  </Provider>,
  rootElement
)

其实客户端渲染也就拿到个初始state,然后render而已,没有很多代码。

我们的state是从window.__INITIAL_STATE__获取的,因为服务端把要给客户端的state放在了这个全局变量上面。

"玄乎"的预载state

预载state,说得这么“玄乎”,好像很高大上,其实就是把state在服务器那边就生成好,然后传过来直接给客户端用。没有那么“玄乎”。


教程源代码及目录

如果您觉得本博客教程帮到了您,就赏颗星吧!

https://github.com/lewis617/react-redux-tutorial

react+redux教程(六)redux服务端渲染流程的更多相关文章

  1. 教你如何在React及Redux项目中进行服务端渲染

    服务端渲染(SSR: Server Side Rendering)在React项目中有着广泛的应用场景 基于React虚拟DOM的特性,在浏览器端和服务端我们可以实现同构(可以使用同一份代码来实现多端 ...

  2. 详解react/redux的服务端渲染:页面性能与SEO

        亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)   react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...

  3. 【redux】详解react/redux的服务端渲染:页面性能与SEO

        亟待解决的疑问 为什么服务端渲染首屏渲染快?(对比客户端首屏渲染)   react客户端渲染的一大痛点就是首屏渲染速度慢问题,因为react是一个单页面应用,大多数的资源需要在首次渲染前就加载 ...

  4. (十分钟视频教程)nodejs基础实战教程3:react服务端渲染入门篇

    视频截图如下: (具体视频见文末) 前言: 这是小猫的第三篇node教程,本篇内容是由公众号粉丝票选得出的,相信大家对这篇教程是抱有较大希望的,这篇教程由小猫和一位多年的好朋友合作完成(笔名:谷雨,博 ...

  5. React服务端渲染总结

    欢迎吐槽 : ) 本demo地址( 前端库React+mobx+ReactRouter ):https://github.com/Penggggg/react-ssr.本文为笔者自学总结,有错误的地方 ...

  6. react服务端渲染框架

    客户端渲染 加载一个空的html页面,然后请求一个打包的js文件,然后再客户端执行这个js文件 动态生成html内容然后插入到DOM元素上,在源代码查询中也只能看到空的html文档 没有任何其他内容 ...

  7. react服务端渲染(同构)

    学习react也有一段时间了,使用react后首页渲染的速度与seo一直不理想.打算研究一下react神奇服务端渲染. react服务端渲染只能使用nodejs做服务端语言实现前后端同构,在后台对re ...

  8. React 在服务端渲染的实现

    原文地址:Server-Side React Rendering 原文作者:Roger Jin 译者:牧云云 React 在服务端渲染的实现 React是最受欢迎的客户端 JavaScript 框架, ...

  9. [译]React 在服务端渲染的实现

    原文地址:Server-Side React Rendering 原文作者:Roger Jin React 在服务端渲染的实现 React是最受欢迎的客户端 JavaScript 框架,但你知道吗(可 ...

随机推荐

  1. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  2. 【接口开发】浅谈 SOAP Webserver 与 Restful Webserver 区别

    接口,强大,简单,交互,跨越平台 下面简单阐述这两大接口思想 一 REST: REST是一种架构风格,其核心是面向资源,REST专门针对网络应用设计和开发方式,以降低开发的复杂性,提高系统的可伸缩性. ...

  3. Xamarin+Prism开发详解二:Xaml文件如何简单绑定Resources资源文件内容

    我们知道在UWP里面有Resources文件xxx.resx,在Android里面有String.Xml文件等.那跨平台如何统一这些类别不一的资源文件以及Xaml设计文件如何绑定这些资源?应用支持多国 ...

  4. ASP.NET Core CORS 简单使用

    CORS 全称"跨域资源共享"(Cross-origin resource sharing). 跨域就是不同域之间进行数据访问,比如 a.sample.com 访问 b.sampl ...

  5. Anders Hejlsberg 技术理想架构开发传奇

    Anders Hejlsberg(安德斯-海森博格) 坐在自己的办公室,双眼直直的盯着前方.他要做一个决定,决定自己未来的命运和理想.这是1996年一个普通的下午,几个小时前,他刚与比尔-盖茨结束了 ...

  6. stringstream的基本用法

    原帖地址:https://zhidao.baidu.com/question/580048330.htmlstringstream是字符串流.它将流与存储在内存中的string对象绑定起来.在多种数据 ...

  7. jQuery个性化图片轮播效果

    jQuery个性化图片轮播效果 购物产品展示:图片轮播器<效果如下所示> 思路说明: 每隔一段时间,实现图片的自动切换及选项卡选中效果,鼠标划入图片动画停止,划出或离开动画开始 两个区域: ...

  8. 【干货分享】流程DEMO-外出申请

    流程名: 外出申请  流程相关文件: 流程包.xml  流程说明: 直接导入流程包文件,即可使用本流程  表单:   流程: 图片:2.png DEMO包下载: http://files.cnblog ...

  9. GitHub管理代码-随笔

    公司一直用的SVN进行项目管理,平时便自己折腾了下Git,这里做下GitHub的最简单的记录... 在git上创建仓库等就免谈了,网上也有好多教程,直接从创建之后记录: 在github的readme文 ...

  10. Linux基础介绍【第八篇】

    Linux网络基础 网线 568A 568B 线序:橙白橙 绿白蓝 蓝白绿 棕白棕 交换机.路由器 交换机:DLINK.H3C.CISCO 交换机(Switch)是一种用于电信号转发的网络设备.它可以 ...