react 服务器端渲染_使用PHP的服务器端React –第2部分

react 服务器端渲染

react 服务器端渲染

Part 1 ended with todos. The first one was to couple the server-side generated code with the client-side React, so that any updates past the initial page load will be handled by React's client JS, which is where React shines. Let's see how you can do just that.

第1部分以待办事项结尾。 第一个是将服务器端生成的代码与客户端React耦合,以便超过初始页面加载的任何更新都将由React的客户端JS处理,这是React的亮点。 让我们看看如何做到这一点。

PHP数据获取,将JS for v8粘合 (PHP data fetch, gluing JS for v8)

This part is the same as before, pasting here with no additional comments. The point is: you fetch the data with PHP somehow. You concatenate React with your app, pass the PHP data to the app and get ready to execute this JS with v8. (The concat stuff could, and should, be done by a build process actually, not at runtime, but this is just an illustration)

此部分与之前相同,在此处粘贴,没有其他注释。 关键是:您以某种方式使用PHP获取数据。 您将React与您的应用程序连接起来,将PHP数据传递给应用程序,并准备好使用v8执行此JS。 (concat的东西实际上可以并且应该由构建过程来完成,而不是在运行时完成,但这只是一个示例)

<?php
$react = array();
 
// stubs, react
$react[] = "var console = {warn: function(){}, error: print}";
$react[] = "var global = {}";
$react[] = file_get_contents('react/build/react.js');
$react[] = "var React = global.React";
 
// my custom components
$react[] = file_get_contents('react/build/table.js');
 
// my application, fetch the data
$data = array( // database, web services, whatevers
    array(1, 2, 3),
    array(4, 5, 6),
    array(7, 8, 9));
// my application, render the data
$react[] = sprintf(
  "React.renderComponentToString(Table({data: %s}), print)",
  json_encode($data));
 
// concat all JS
$react = implode(";\n", $react);

运行JS并缓冲 (Run JS and buffer)

While before I just printed the result of the JS code (which is rendered HTML), here I want to keep it in a variable and use it later as part of a bigger template. So I execute the JS string but buffer the output to a variable. (I tried without a buffer, only using the return value of $v8->executeString() but couldn't make it happen, as React's renderComponentToString() is async and takes a callback)

在我刚刚打印JS代码(呈现为HTML)的结果之前,这里我想将其保留在变量中,以后将其用作更大的模板的一部分。 因此,我执行JS字符串,但将输出缓冲到变量中。 (我尝试不使用缓冲区,仅使用$v8->executeString()的返回值,但无法实现,因为React的renderComponentToString()是异步的并且需要回调)

$v8 = new V8Js();
try {
  // buffer v8 output to $markup
  ob_start();
  $v8->executeString($react);
  $markup = ob_get_clean();
} catch (V8JsException $e) {
  // blow up spectacularly
  echo "<pre>"; var_dump($e); die();
}

呈现整个页面 (Render a whole page)

Finally, you take the rendered markup and replace a simple template which takes care of all the html/body/doctype, etc. Then you print it out.

最后,使用呈现的标记并替换一个简单的模板,该模板处理所有html / body / doctype等。然后将其打印出来。

// page template
$page = file_get_contents('page_template.html');
 
printf($page, $markup, json_encode($data));

In fact, this template will also take care of initializing React on the client.

实际上,该模板还将负责在客户端上初始化React。

模板/客户端 (The template/client)

So what goes into this page_template.html? It takes care of the HTML boilerplate, load CSS, and so on. Then it puts all the server-rendered HTML in a div id=page. Finally it loads React.js and custom app .js (which could very well be concatenated into one). Once React is loaded you initialize the client-side, by passing the same $data used to render server-side.

那么,此page_template.html什么? 它负责处理HTML样板文件,加载CSS等。 然后将所有服务器呈现HTML放入div id=page 。 最后,它加载React.js和自定义应用程序.js(可以很好地合并为一个)。 一旦加载了React,您就可以通过传递用于渲染服务器端的$data来初始化客户端。

<!doctype html>
<html>
  <head>
    <title>React page</title>
    <!-- css and stuff -->
  </head>
  <body>
    
    <!-- render server content here -->
    <div id="page">%s</div> 
    
    <!-- load react and app code -->
    <script src="react/build/react.min.js"></script>
    <script src="react/build/table.js"></script>
    
    <script>
    // client init/render
    var r = React.renderComponent(
      Table({data: %s}), 
      document.getElementById('page'));
    </script>
  </body>
</html>

So clearly there's a duplication of the data sent to the client: once rendered as HTML and once JSON-encoded. But the JSON encoded data should be very small in most cases. Alternatively you can always DOM-scrape the rendered HTML for the data and pass that back to React, but in most cases the scraping code will probably be longer than the JSON encoded thing.

显然,发送给客户端的数据是重复的:一次呈现为HTML,一次以JSON编码。 但是在大多数情况下,JSON编码的数据应该很小。 或者,您总是可以对数据的呈现HTML进行DOM爬取,然后将其传递回React,但是在大多数情况下,爬取代码可能比JSON编码的要长。

Yet another strategy is to flush only partial data rendered as HTML, only as much (or as little) as needed to make the page appear responsive. Then in a second flush pass all the data as JSON and let React update the UI.

另一策略是仅刷新呈现为HTML的部分数据,仅刷新(或减少)所需的数量,以使页面显示响应。 然后在第二次刷新中将所有数据作为JSON传递,并让React更新UI。

结果 (Results)

Rendered markup on the server:

服务器上的渲染标记:

1

Updating the data client-side to make sure client React is initialized and knows what it's doing

在客户端更新数据以确保客户端React已初始化并知道它在做什么

e2

Here's a static version of the end result (can't install v8 on dreamhost's shared server) if you want to explore.

如果您想探索的话,这是最终结果静态版本(无法在Dreamhost的共享服务器上安装v8)。

请享用! (Enjoy!)

Thanks for reading, now go play with React. Meanwhile I'll try to clean this code up and setup a standalone project you can fork.

感谢您的阅读,现在开始玩React。 同时,我将尝试清理此代码并设置一个可以分叉的独立项目。

Tell your friends about this post on Facebook and Twitter

FacebookTwitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/server-side-react-with-php-part-2/

react 服务器端渲染

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值