我的编程空间,编程开发者的网络收藏夹
学习永远不晚

React服务器端渲染怎么用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

React服务器端渲染怎么用

这篇文章给大家分享的是有关React服务器端渲染怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

React 提供了两个方法 renderToString 和 renderToStaticMarkup 用来将组件(Virtual DOM)输出成 HTML 字符串,这是 React 服务器端渲染的基础,它移除了服务器端对于浏览器环境的依赖,所以让服务器端渲染变成了一件有吸引力的事情。

服务器端渲染除了要解决对浏览器环境的依赖,还要解决两个问题:

  1. 前后端可以共享代码

  2. 前后端路由可以统一处理

React 生态提供了很多选择方案,这里我们选用 Redux 和 react-router 来做说明。

Redux

Redux 提供了一套类似 Flux 的单向数据流,整个应用只维护一个 Store,以及面向函数式的特性让它对服务器端渲染支持很友好。

2 分钟了解 Redux 是如何运作的

关于 Store:

  1. 整个应用只有一个唯一的 Store

  2. Store 对应的状态树(State),由调用一个 reducer 函数(root reducer)生成

  3. 状态树上的每个字段都可以进一步由不同的 reducer 函数生成

  4. Store 包含了几个方法比如 dispatch, getState 来处理数据流

  5. Store 的状态树只能由 dispatch(action) 来触发更改

Redux 的数据流:

  1. action 是一个包含 { type, payload } 的对象

  2. reducer 函数通过 store.dispatch(action) 触发

  3. reducer 函数接受 (state, action) 两个参数,返回一个新的 state

  4. reducer 函数判断 action.type 然后处理对应的 action.payload 数据来更新状态树

所以对于整个应用来说,一个 Store 就对应一个 UI 快照,服务器端渲染就简化成了在服务器端初始化 Store,将 Store 传入应用的根组件,针对根组件调用 renderToString 就将整个应用输出成包含了初始化数据的 HTML。

react-router

react-router 通过一种声明式的方式匹配不同路由决定在页面上展示不同的组件,并且通过 props 将路由信息传递给组件使用,所以只要路由变更,props 就会变化,触发组件 re-render。

假设有一个很简单的应用,只有两个页面,一个列表页 /list 和一个详情页 /item/:id,点击列表上的条目进入详情页。

可以这样定义路由,./routes.js

import React from 'react';
import { Route } from 'react-router';
import { List, Item } from './components';

// 无状态(stateless)组件,一个简单的容器,react-router 会根据 route
// 规则匹配到的组件作为 `props.children` 传入
const Container = (props) => {
 return (
  <div>{props.children}</div>
 );
};

// route 规则:
// - `/list` 显示 `List` 组件
// - `/item/:id` 显示 `Item` 组件
const routes = (
 <Route path="/" component={Container} >
  <Route path="list" component={List} />
  <Route path="item/:id" component={Item} />
 </Route>
);

export default routes;

从这里开始,我们通过这个非常简单的应用来解释实现服务器端渲染前后端涉及的一些细节问题。

Reducer

Store 是由 reducer 产生的,所以 reducer 实际上反映了 Store 的状态树结构

./reducers/index.js

import listReducer from './list';
import itemReducer from './item';

export default function rootReducer(state = {}, action) {
 return {
  list: listReducer(state.list, action),
  item: itemReducer(state.item, action)
 };
}

rootReducer 的 state 参数就是整个 Store 的状态树,状态树下的每个字段对应也可以有自己的reducer,所以这里引入了 listReducer 和 itemReducer,可以看到这两个 reducer的 state 参数就只是整个状态树上对应的 list 和 item 字段。

具体到 ./reducers/list.js

const initialState = [];

export default function listReducer(state = initialState, action) {
 switch(action.type) {
 case 'FETCH_LIST_SUCCESS': return [...action.payload];
 default: return state;
 }
}

list 就是一个包含 items 的简单数组,可能类似这种结构:[{ id: 0, name: 'first item'}, {id: 1, name: 'second item'}],从 'FETCH_LIST_SUCCESS' 的 action.payload 获得。

然后是 ./reducers/item.js,处理获取到的 item 数据

const initialState = {};

export default function listReducer(state = initialState, action) {
 switch(action.type) {
 case 'FETCH_ITEM_SUCCESS': return [...action.payload];
 default: return state;
 }
}

Action

对应的应该要有两个 action 来获取 list 和 item,触发 reducer 更改 Store,这里我们定义 fetchList 和 fetchItem 两个 action。

./actions/index.js

import fetch from 'isomorphic-fetch';

export function fetchList() {
 return (dispatch) => {
  return fetch('/api/list')
    .then(res => res.json())
    .then(json => dispatch({ type: 'FETCH_LIST_SUCCESS', payload: json }));
 }
}

export function fetchItem(id) {
 return (dispatch) => {
  if (!id) return Promise.resolve();
  return fetch(`/api/item/${id}`)
    .then(res => res.json())
    .then(json => dispatch({ type: 'FETCH_ITEM_SUCCESS', payload: json }));
 }
}

isomorphic-fetch 是一个前后端通用的 Ajax 实现,前后端要共享代码这点很重要。

另外因为涉及到异步请求,这里的 action 用到了 thunk,也就是函数,redux 通过 thunk-middleware 来处理这类 action,把函数当作普通的 action dispatch 就好了,比如 dispatch(fetchList())

Store

我们用一个独立的 ./store.js,配置(比如 Apply Middleware)生成 Store

import { createStore } from 'redux';
import rootReducer from './reducers';

// Apply middleware here
// ...

export default function configureStore(initialState) {
 const store = createStore(rootReducer, initialState);
 return store;
}

react-redux

接下来实现 <List>,<Item> 组件,然后把 redux 和 react 组件关联起来,具体细节参见 react-redux

./app.js

import React from 'react';
import { render } from 'react-dom';
import { Router } from 'react-router';
import createBrowserHistory from 'history/lib/createBrowserHistory';
import { Provider } from 'react-redux';
import routes from './routes';
import configureStore from './store';

// `__INITIAL_STATE__` 来自服务器端渲染,下一部分细说
const initialState = window.__INITIAL_STATE__;
const store = configureStore(initialState);
const Root = (props) => {
 return (
  <div>
   <Provider store={store}>
    <Router history={createBrowserHistory()}>
     {routes}
    </Router>
   </Provider>
  </div>
 );
}

render(<Root />, document.getElementById('root'));

至此,客户端部分结束。

Server Rendering

接下来的服务器端就比较简单了,获取数据可以调用 action,routes 在服务器端的处理参考 react-router server rendering,在服务器端用一个 match 方法将拿到的 request url 匹配到我们之前定义的 routes,解析成和客户端一致的 props 对象传递给组件。

./server.js

import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { RoutingContext, match } from 'react-router';
import { Provider } from 'react-redux';
import routes from './routes';
import configureStore from './store';

const app = express();

function renderFullPage(html, initialState) {
 return `
  <!DOCTYPE html>
  <html lang="en">
  <head>
   <meta charset="UTF-8">
  </head>
  <body>
   <div id="root">
    <div>
     ${html}
    </div>
   </div>
   <script>
    window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};
   </script>
   <script class="lazy" data-src="/static/bundle.js"></script>
  </body>
  </html>
 `;
}

app.use((req, res) => {
 match({ routes, location: req.url }, (err, redirectLocation, renderProps) => {
  if (err) {
   res.status(500).end(`Internal Server Error ${err}`);
  } else if (redirectLocation) {
   res.redirect(redirectLocation.pathname + redirectLocation.search);
  } else if (renderProps) {
   const store = configureStore();
   const state = store.getState();

   Promise.all([
    store.dispatch(fetchList()),
    store.dispatch(fetchItem(renderProps.params.id))
   ])
   .then(() => {
    const html = renderToString(
     <Provider store={store}>
      <RoutingContext {...renderProps} />
     </Provider>
    );
    res.end(renderFullPage(html, store.getState()));
   });
  } else {
   res.status(404).end('Not found');
  }
 });
});

服务器端渲染部分可以直接通过共用客户端 store.dispatch(action) 来统一获取 Store 数据。另外注意 renderFullPage 生成的页面 HTML 在 React 组件 mount 的部分(<div id="root">),前后端的 HTML 结构应该是一致的。然后要把 store 的状态树写入一个全局变量(__INITIAL_STATE__),这样客户端初始化 render 的时候能够校验服务器生成的 HTML 结构,并且同步到初始化状态,然后整个页面被客户端接管。

最后关于页面内链接跳转如何处理?

react-router 提供了一个 <Link> 组件用来替代 <a> 标签,它负责管理浏览器 history,从而不是每次点击链接都去请求服务器,然后可以通过绑定 onClick 事件来作其他处理。

比如在 /list 页面,对于每一个 item 都会用 <Link> 绑定一个 route url:/item/:id,并且绑定 onClick 去触发 dispatch(fetchItem(id)) 获取数据,显示详情页内容。

感谢各位的阅读!关于“React服务器端渲染怎么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

React服务器端渲染怎么用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

使用React怎么对服务端进行渲染

使用React怎么对服务端进行渲染?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。服务器端编写 React 组件如果是客户端渲染,浏览器首先会向浏览器发送请求,服
2023-06-06

React服务端渲染和同构怎么实现

这篇文章主要讲解了“React服务端渲染和同构怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“React服务端渲染和同构怎么实现”吧!背景第一阶段很久以前, 一个网站的开发还是前端和服
2023-06-30

客户端渲染(CSR)与服务器端渲染(SSR)

在比较服务器端渲染(SSR)和客户端渲染(CSR)时,重要的是考虑性能的不同方面,

怎么使用React虚拟渲染实现多个图表渲染

今天小编给大家分享一下怎么使用React虚拟渲染实现多个图表渲染的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。需求每行渲染3
2023-07-02

面试官:说说React服务端渲染怎么做?原理是什么?

在SSR中,我们了解到Server-Side Rendering ,简称SSR,意为服务端渲染。指由服务侧完成页面的 HTML 结构拼接的页面处理技术,发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的过程。

快速在你的Vue/React应用中实现SSR(服务端渲染)

服务端渲染(ssr),是指由服务器端完成页面的HTML 结构拼接,并且直接将拼接好的HTML发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的处理技术。

编程热搜

目录