基于React+Redux的SSR实现

  • 时间:
  • 浏览:0
  • 来源:大发彩神app—大发彩神8苹果版

实现的最关键一步若果创建

最后2个都要优化的地方,若果当原困取到users时,都要阻止fetch

有了后面 的代码,我们歌词 我们歌词 的组件原困可不能不能 成功地在服务器端渲染。通过开发者工具,我们歌词 我们歌词 可不能不能 想看 发送到浏览器的内容:

服务器端呈现是2个有趣搞笑的话题。它有一点一点优势,并改善了整体用户体验。它总要提升你的单页程序运行运行的SEO。但一点切暂且简单。在大多数状况下,都要额外的工具和精心选折 的api。

import ReactDOM from 'react-dom';

ReactDOM.render(
  <Provider store={ createStore() }><App /></Provider>,
  document.querySelector('#content')
);

注意typeof window !== 'undefined',我们歌词 我们歌词 都要若果做,原困这段代码也会在服务端执行,这若果为社 么说在做服务端渲染都要非常小心,尤其是全局使用的浏览器api的以前 。

最后2个有用的命令,用于运行我们歌词 我们歌词 的http服务器:

我们歌词 我们歌词 使用了相同的组件<App />和 store,不同之存在于它返回的是2个字符串,而总要虚拟DOM。

store.subscribe法律措施返回2个函数,调用一点函数就可不能不能 解除监听

2、我们歌词 我们歌词 删剪依赖于运行在客户端上的代码,计算出最终的结果。

这若果2个简单的案例,实际开发场景往往比一点多样化的多,都要考虑的状况也会非常多,我们歌词 我们歌词 的服务端渲染是为社 么做的?

原困重新启动服务器并打开相同的

我们歌词 我们歌词 都要保证代码能在服务端正常的运行。类似,访问Window对象,Node不提供Window对象的访问。

我们歌词 我们歌词 在package.json后面 加入以下2个命令脚本:

我们歌词 我们歌词 通过2个组件将数据渲染出来。在一点组件的componentWillMount生命周期法律措施中,我们歌词 我们歌词 将触发数据获取,一旦请求成功,我们歌词 我们歌词 将发送2个类型为user_fetch的操作。该操作将由2个reducer补救,我们歌词 我们歌词 将在Redux存储中获得更新。状况的改变将触发我们歌词 我们歌词 的组件重新呈现指定的数据。

我们歌词 我们歌词 使用客户端API接收异步数据,一旦Store获取到异步数据,我们歌词 我们歌词 将触发ReactDOMServer.renderToString。它会提供给我们歌词 我们歌词 不让的标记。我们歌词 我们歌词 的Express补救器是若果的:

<html>
          <head>
            <title>App</title>
            <style>
              body {
                font-size: 18px;
                font-family: Verdana;
              }
            </style>
          </head>
          <body>
            <div id="content"><div data-reactroot=""><p>Eve Holt</p><p>Charles Morris</p><p>Tracey Ramos</p></div></div>
            <script>
              window.__APP_STATE = {"users":[{"id":4,"first_name":"Eve","last_name":"Holt","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"},{"id":5,"first_name":"Charles","last_name":"Morris","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"},{"id":6,"first_name":"Tracey","last_name":"Ramos","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"}]};
            </script>
            <script src="/bundle.js"></script>
          </body>
        </html>

为社 么直接返回的是工厂函数而总要createStore(reducer)?这原困我们歌词 我们歌词 我们歌词 在服务器端渲染时,我们歌词 我们歌词 都要2个全新的Store实例来补救每个请求。

第类似于法律措施,都不让们歌词 我们歌词 在两端做好状况管理。第二种法律措施都不让们歌词 我们歌词 在服务端使用一点额外的库或工具,来确保同一套代码能在服务端和客户端做相同的事情,我买车人比较推荐使用一点法律措施。

总结下来有以下几点:

目前为止,我们歌词 我们歌词 的服务端仅仅是返回了2个html骨架,而所有交互全在客户端完成。浏览器都要先下载bundle.js后执行。而服务端渲染的作用若果在服务器上执行所有操作并发送最终标记,而总要把所有工作交给浏览器执行。React足够的聪明,也能识别出什么标记。

还记得我们歌词 我们歌词 在客户端做的以下事情吗?

为了演示方便,我们歌词 我们歌词 首选Express作为http服务器。

在刚刚刚刚刚开始 英文编写应用以前 ,都不让们歌词 我们歌词 先把环境编译/打包环境配置好,原困我们歌词 我们歌词 采用的是es6语法编写代码。我们歌词 我们歌词 都要将代码编译成es5代码在浏览器或node环境中执行。

:

你想看 ,我们歌词 我们歌词 使用componentWillMount来发送fetchUsers请求,componentDidMount为社 么非要用呢? 主要原困是componentDidMount在服务端渲染过程中暂且会执行。

当然,现在并没法 刚刚刚刚刚开始 英文,客户端JavaScript谁能谁能告诉我服务器上存在了什么,也谁能谁能告诉我我们歌词 我们歌词 原困对API进行了请求。我们歌词 我们歌词 都要通过传递Store的状况来通知浏览器,以便它也能接收它。

为了能分类分类整理

concurrently库帮助并行运行多个程序运行,这正是我们歌词 我们歌词 在监控更改时都要的。

今天我们歌词 我们歌词 将构建2个使用Redux的简单的React程序运行运行,实现服务端渲染(SSR)。该示例包括异步数据抓取,这使得任务变得更有趣。

类似,我们歌词 我们歌词 使用了Fetch API向后端发出异步请求,而服务端默认是不支持的。我们歌词 我们歌词 都要做的若果在server.js中将Fetch导入:

原文作者:感叹句

1、我们歌词 我们歌词 明确知道请求的页面都要什么样的数据。我们歌词 我们歌词 获取数据并使用该数据创建Redux存储。一点我们歌词 我们歌词 通过提供已完成的Store来呈现页面,理论上我们歌词 我们歌词 可不能不能 做到。

有了一点文件,我们歌词 我们歌词 可不能不能 运行npm run start并访问http://localhost:10000。我们歌词 我们歌词 想看 数据获取成功,并成功的显示了。

我们歌词 我们歌词 的页面中真是有一点内容,但它若果<div data-reactroot=""></div>。这暂且原困程序运行出错了。这绝对是正确的。React真是呈现了我们歌词 我们歌词 的页面,但它只呈现静态内容。在我们歌词 我们歌词 的组件中,我们歌词 我们歌词 在获取数据以前 一点一点没法 ,数据的获取是2个异步过程,在服务器上呈现时,我们歌词 我们歌词 都要考虑到一点点。这若果我们歌词 我们歌词 的任务变得棘手的地方。这可不能不能 归结为我们歌词 我们歌词 的程序运行运行在做什么。在本例中,客户端代码依赖于2个特定的请求,但原困使用redux-saga库,则原困是多个请求,原困原困是2个删剪的root saga。我意识到补救一点问題报告 的类似于法律措施:

在这里都要提的2个重点是,一旦我们歌词 我们歌词 想实现服务端渲染,若果们就都要改变以前 的纯客户端编程模式。

请求去改变应用状况,我们歌词 我们歌词 都要编写

一点将一点字符串加入到Express的响应后面 ,一点一点服务端代码为:

不使用node ./build/server/server.js而使用Nodemon的原困是,它可不能不能 监控我们歌词 我们歌词 代码中的任何更改,并自动重新启动服务器。一点点在开发过程会非常有用。

// App.jsx
import React from 'react';
import { connect } from 'react-redux';

import { getUsers } from './redux/selectors';
import { usersFetched } from './redux/actions';

const ENDPOINT = 'http://localhost:10000/users_fake_data.json';

class App extends React.Component {
  componentWillMount() {
    fetchUsers();
  }
  render() {
    const { users } = this.props;

    return (
      <div>
        {
          users && users.length > 0 && users.map(
            // ... render the user here
          )
        }
      </div>
    );
  }
}

const ConnectedApp = connect(
  state => ({
    users: getUsers(state)
  }),
  dispatch => ({
    fetchUsers: async () => dispatch(
      usersFetched(await (await fetch(ENDPOINT)).json())
    )
  })
)(App);

export default ConnectedApp;

,我们歌词 我们歌词 将想看 以下响应:

假设服务端返回以下的数据格式:

服务端几乎相同:

fetchUsers是2个异步函数,它通过Fetch API请求数据。当数据返回时,会分类分类整理users_fetch动作,从而通过reducer重新计算状况,而我们歌词 我们歌词 的<App />原困连接到Redux从而被重新渲染。

本文来源: 掘金 如需转载请联系原作者

我们歌词 我们歌词 将用babelify转换来使用browserify和watchify来打包我们歌词 我们歌词 的客户端代码。对于我们歌词 我们歌词 的服务器端代码,我们歌词 我们歌词 将直接使用babel-cli。

我们歌词 我们歌词 使用Storesubscribe法律措施来监听状况。当状况存在变化——是是是不是有任何用户数据被获取。原困users存在,我们歌词 我们歌词 将unsubscribe(),若果我们歌词 我们歌词 就不让让相同的代码运行两次,一点我们歌词 我们歌词 使用相同的存储实例转换为string。最后,我们歌词 我们歌词 将标记输出到浏览器。

服务器端渲染,也叫代码同构,也若果同一份代码既能在客户端渲染,又能在服务端渲染。

原困您想使用本文中讨论的代码,请查看GitHub: answer518/react-redux-ssr

reducer补救过程如下:

代码行态如下: