如何使用 api 在服务器端呈现反应?

Posted

技术标签:

【中文标题】如何使用 api 在服务器端呈现反应?【英文标题】:How to render react on server-side with an api? 【发布时间】:2017-07-17 06:27:42 【问题描述】:

为了清楚起见,我使用的是 MongoDB、Express、React 和 Node 堆栈。

我现在正在尝试学习 react.js。我掌握了正确的基础知识,并且能够使用路由器编写一个简单的反应应用程序。我还尝试过在服务器端渲染一个简单的反应应用程序,它也可以完美运行。但是,我现在有点卡住了,因为我想制作一个带有 rest api 和服务器端渲染的完整应用程序。

1) 我不知道应该如何在服务器文件中分离 api 和 react 代码。会从列出 api 调用开始,然后进行服务器端渲染工作吗? 像这样:

app.get('/api/whatever', function(req, res) 
    //get whatever
);
app.get('*', function(req, res) 
    //math routes and renderToString React
);

2)另外,我什至无法测试上述内容的原因是,当我尝试使用 nodemon 运行服务器时,它会抛出错误,因为它不理解反应代码,我应该怎么做呢?我应该以某种方式配置 nodemon 以读取 es6 还是忽略它或配置 webpack 以运行 express 服务器?

3) 最后一个问题可以很容易地弄清楚整个故事。我试图找到一个答案,但得到了许多相互矛盾的答案。谷歌爬虫是否能够爬取 React 应用程序?我正在学习 SEO 的服务器端渲染,真的有必要吗?

抱歉问题太长了,期待阅读您的回答。

【问题讨论】:

你在第二个 app.get 函数中给出了什么响应? app.get("*",function(req, res) ReactRouter.match(routes:AppRoutes, location:req.url, function(err, redirectLocation, renderProps) if ( err) res.send(500, err.message) else if (redirectLocation) res.redirect(302, redirectLocation.pathname + redirectLocation.search) else if (renderProps) res.send(200, ReactDOMServer.renderToString ()) else res.send(404, 'Not found') ); ); 我将在问题中添加整个函数作为编辑。这看起来不对... 是的,nodemon 显示的错误是什么? 【参考方案1】:

    我的做法与您在我目前正在处理的项目中的代码示例中的做法相同——我匹配 *,然后使用 React Router 呈现不同的页面。 I wrote a blog article about this, with code examples.

    在我的设置中,我使用 webpack 来编译我的后端代码,就像我使用前端代码一样。我使用 watch 机制来监听代码的变化,并在重新编译后自动重启节点服务器。不需要nodemon。

#!/usr/bin/env node

const path = require('path');
const webpack = require('webpack');
const spawn = require('child_process').spawn;
const serverConfig = require('webpack.config.server');

const compiler = webpack(serverConfig);
const watchConfig = 
    aggregateTimeout: 300,
    poll: 1000,
    ignored: '**/*.scss'
;

let serverControl;

compiler.watch(watchConfig, (err, stats) => 
    if (err) 
        console.error(err.stack || err);
        if (err.details) 
            console.error(err.details);
        
        return;
    

    const info = stats.toJson();

    if (stats.hasErrors()) 
        info.errors.forEach(message => console.log(message));
        return;
    

    if (stats.hasWarnings()) 
        info.warnings.forEach(message => console.log(message));
    

    if (serverControl) 
        serverControl.kill();
    

    serverControl = spawn('node', [path.resolve(__dirname, '../../dist/polly-server.js')]);
    serverControl.stdout.on('data', data => console.log(`$new Date().toISOString() [LOG] $data`));
    serverControl.stderr.on('data', data => console.error(`$new Date().toISOString() [ERROR] $data`));
);
    是的,Google 会抓取客户端的 React 代码,但服务器端渲染仍然是个好主意,因为抓取结果可能会不一致,尤其是在 Ajax 调用后动态加载部分页面时

【讨论】:

感谢您的回答,这正是我所希望的。但是,在您博客文章的演示中,您从 git hub api 获取数据。有一个存在于 server.js 文件中的 api 会起作用吗? '*' 不会与 '/api' 冲突,因为它处理所有请求吗?我想我会尝试一下,看看会发生什么。 没有冲突,只要确保你的 * 匹配在最后,顺序很重要

以上是关于如何使用 api 在服务器端呈现反应?的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中呈现html表格?

react + redux + saga +服务器端渲染+如何停止服务器端渲染页面的额外ajax调用?

Next Js API:使用 s-s-r 反应页面的响应

如何在反应服务器端渲染中正确处理 window=undefined 错误

尽管所有反应路由器版本冲突,如何在反应中进行服务器端渲染?

如何将我的 API 中的数据设置为我的反应组件的初始状态?