当前位置: 首页 > 面试题库 >

使用React,React-Router和Express进行服务器端渲染

巫马磊
2023-03-14
问题内容

我正在尝试为我的react应用设置服务器端渲染,并且试图使用出色的react-router模块来处理非js情况(某些爬虫,当用户关闭js时,原因)。但是,我遇到了麻烦。我一直在这里使用出色的响应作为各种指南,但我却遇到了奇怪的错误。Syntax Error尝试使用时,我会坚持不懈react.renderToString()。我是否设置了服务器端渲染错误,缺少明显的东西或其他东西?

我的设置:

真正的基本Express服务器

require('babel/register');

var app = express();


// misc. express config...

var Router = require('react-router'),
    routes = require('../jsx/app').routes,
    React = require('react');


app.use(function(req, res, next) {
  var router = Router.create({location: req.url, routes: routes});
  router.run(function(Handler, state) {
    console.log(Handler);
    var html = React.renderToString(<Handler/>);
    return res.render('react_page', {html: html});
  });
});

顶级反应<App/>组件

// Shims
require('intl');
require('es5-shim');

var React = require('react/addons'),
  Router = require('react-router'),
  Nav = require('./nav'),
  injectTapEventPlugin = require("react-tap-event-plugin"),


  window.React = React; // export for http://fb.me/react-devtools

// Intl
var ReactIntl = require('react-intl'),
  IntlMixin = ReactIntl.IntlMixin;

var Route = Router.Route,
  DefaultRoute = Router.DefaultRoute,
  NotFoundRoute = Router.NotFoundRoute,
  RouteHandler = Router.RouteHandler;


var App = React.createClass({
      mixins: [IntlMixin],

      getInitialState: function() {
        return {
          connected: false,
          loaded: false,
          user: true
        };
      },
      render: function() {
          return ( 
            <div className="container-fluid">
              <Nav/>
              <RouteHandler/>
              <Footer/>
            </div>
      );
  }

});

var routes = (
<Route name="Home" path="/" handler={App}>
    <DefaultRoute name="Welcome " handler={Welcome}/>
    <Route name="Bar" path="/bar" handler={Bar}>
    <Route name="foo" path="/foo" handler={Foo}></Route>
 </Route>
);

Router.run(routes, Router.HistoryLocation , function(Handler) {
  React.render(<Handler/>, document.getElementById('app'));
});

module.routes = routes;

输出:

flo-0,1,2 (err):       <div className="progressbar-container" >
flo-0,1,2 (err):       ^
flo-0,1,2 (err): SyntaxError: Unexpected token <
flo-0,1,2 (err):     at exports.runInThisContext (vm.js:73:16)
flo-0,1,2 (err):     at Module._compile (module.js:443:25)
flo-0,1,2 (err):     at Module._extensions..js (module.js:478:10)
flo-0,1,2 (err):     at Object.require.extensions.(anonymous function) [as .js] (/Users/user/Code/foobar/apps/flo/node_modules/babel/node_modules/babel-core/lib/babel/api/register/node.js:161:7)
flo-0,1,2 (err):     at Module.load (module.js:355:32)
flo-0,1,2 (err):     at Function.Module._load (module.js:310:12)
flo-0,1,2 (err):     at Function.<anonymous> (/Users/user/.nvm/versions/node/v0.12.4/lib/node_modules/pm2/node_modules/pmx/lib/transaction.js:62:21)
flo-0,1,2 (err):     at Function.cls_wrapMethod (/Users/user/Code/foobar/apps/bar/node_modules/newrelic/lib/shimmer.js:230:38)
flo-0,1,2 (err):     at Function.<anonymous> (/Users/user/Code/foobar/apps/bar/node_modules/pmx/lib/transaction.js:62:21)
flo-0,1,2 (err):     at Module.require (module.js:365:17)
flo-0,1,2 (err):     at require (module.js:384:17)

问题答案:

因此,我最终自己解决了这个问题。我得到的错误是来自未渲染的嵌套组件,这就是js引擎抱怨随机<字符的原因。

现在到我的快速设置。对于那些不知道如何在服务器端渲染中使用react的人来说,这很简单:Node或io.js可用于renderToString()在组件上调用React的方法,然后将其发送到发出请求的客户端。您可能已经听说过这种方法带来的好处,但是对于那些不知道的人来说:

  1. 即使Google已经可以在其抓取工具中执行JS,您也会获得更多SEO友好性;这几乎只是一个更安全的选择
  2. 非JavaScript情况的后备。如果您的应用程序脚本加载缓慢,您仍然可以将实际页面呈现给客户端,而不必等待凝视空白屏幕。这也使在浏览器上禁用了JS的用户在大多数情况下仍可与您的应用进行交互;链接仍然有效,表单仍然可以提交,&c。
  3. 您可以获得客户端和服务器之间的代码共享的其他好处。除了降低复杂性这一事实外,没有其他事情令人难以置信,因此,您可以获得降低复杂性的所有好处(可能更少的耦合,更容易的可维护性,更简单的结构,同构性等)。
  4. 另一个好处是可以使用react-router的html5历史记录API,而不需要使用其他令人讨厌的哈希片段。

您甚至可能会对这种方法感到疯狂,并在应用程序加载时处理占位符之类的事情,或者为缓慢加载的状态(加载时为Facebook)提供其他反馈机制。

基本方法大致以以下方式运行:

  1. 引导时,节点应用会基于以下实例实例化React-Router实例 routes.jsx
  2. 请求转到服务器,然后服务器使用express’ req.path为react-router处理以提供路由字符串。
  3. 然后,React路由器会匹配提供的路由,并尝试渲染相应的组件以进行快速发回。
  4. React发送html响应,并且您的客户端可以绘制某些内容,而不管您的应用脚本的速度如何。我们通过优质的CDN为我们提供服务,但是即使拥有最佳的分发和压缩速度,慢速的网络仍然会使人们暂时处于空白状态。
  5. 加载了所需的应用程序脚本后,React可以使用相同的routes.jsx文件来接管并生成html react-router。这里的另一个好处是可以缓存您的应用程序代码,希望将来的交互甚至不必依赖另一个调用。

还有一点值得注意:我使用webpack捆绑了我的React代码,现在browser.jsx是入口点。在重构服务器端渲染之前app.jsx,它以前是;您可能需要重新配置结构,以适应在何处渲染的内容。:)

编号:

Browser.jsx

const React = require('react');
const Router = require('react-router').Router;
const hist = require('history');
const routes = require('./routes');

const newHistory = hist.createHistory();

React.render(<Router history={newHistory}>{routes}</Router>, window.document);

App.js(特快服务器)

//...other express configuration

const routes = require('../jsx/routes');
const React = require('react');
const {RoutingContext, match} = require('react-router');
const hist = require('history');

app.use((req, res, next) => {
  const location = hist.createLocation(req.path);
  match({
    routes: routes,
    location: location,
  }, (err, redirectLocation, renderProps) => {
    if (redirectLocation) {
      res.redirect(301, redirectLocation.pathname + redirectLocation.search);
    } else if (err) {
      console.log(err);
      next(err);
      // res.send(500, error.message);
    } else if (renderProps === null) {
      res.status(404)
        .send('Not found');
    } else {
      res.send('<!DOCTYPE html>' + React.renderToString(<RoutingContext {...renderProps}/>));
    }
  });
});

    //...other express configuration

Routes.jsx

<Route path="/" component={App}>
  <DefaultRoute component={Welcome}/>
  <Route path="dashboard" component={Dashboard}/>
  <Route path="login" component={Login}/>
</Route>

App.jsx

<html>
<head>
  <link rel="stylesheet" href="/assets/styles/app.css"/>
</head>
  <body>
    <Navigation/>
    <RouteHandler/>
    <Footer/>
  <body/>
</html>

有用的网址:

  • https://ifelse.io/2015/08/27/server-side-rendering-with-react-and-react-router/
  • https://github.com/rackt/react-router


 类似资料:
  • 原文链接:Serverless 应用开发指南:Serverless + Express 的 React 服务端渲染 我们已经可以用 AWS Lambda 来动态返回 HTML 了。在阅读了一系列的文章后,也发现了 Express 可以在 Lambda 上运行。当我们可以运行 Express 的时候,也意味着,它可以进行服务端渲染,即我们可以做 React 的服务端渲染。 于是,便有了这篇文章,也有

  • 问题内容: 我一直在思考,我对客户端和服务器之间的路由感到困惑。假设我在将请求发送回Web浏览器之前使用ReactJS进行服务器端渲染,并使用react- router作为客户端路由在页面之间切换而不刷新为SPA。 我想到的是: 路线如何解释?例如,从首页()到帖子页面()的请求 路由在服务器端还是客户端去哪里? 它如何知道如何处理? 问题答案: 注意,此答案涵盖了React Router版本0.

  • 我想到的是: 路线是如何解释的?例如,从主页()到帖子页()的请求 路由在服务器端还是客户端? 它如何知道它是如何处理的?

  • 问题内容: 我刚刚学会了最近的反应,打算将其用于下一个项目。我已经遇到过几次反应服务器端渲染,但是想知道为什么在“现代时代”我们仍然需要它。 在本文中,它认为通过服务器端渲染,用户不必等待从CDN或其他地方加载这些js即可看到初始静态页面,并且该页面将在js到达时恢复功能。 但是在使用webpack生产配置和gzip构建之后,整个捆绑包(包括react,我的代码和许多其他东西)仅占用40kb,而我

  • 从节点(express)服务器端渲染时,我无法将初始道具传递到我的React组件 以下是我的组件的简短版本: 这是服务器端 在render()方法中尝试使用组件时,prop似乎没有传递给组件 有什么想法吗?

  • 本文向大家介绍React服务端渲染(总结),包括了React服务端渲染(总结)的使用技巧和注意事项,需要的朋友参考一下 一、前言 为什么需要服务端渲染?什么情况下进行服务端渲染?笔者认为,当我们要求渲染时间尽量快、页面响应速度快时(优点),才会采用服务器渲染,并且应该“按需”对页面进行渲染 ——“首次加载/首屏”。即服务端渲染的优势在于:由中间层( node端 )为客户端请求初始数据、并由node