结合 react 和玉

Posted

技术标签:

【中文标题】结合 react 和玉【英文标题】:Combining react and jade 【发布时间】:2015-06-06 10:58:27 【问题描述】:

我正在开发一个带有 express + react 的同构 javascript 应用程序。我们开始使用jade 作为静态内容的服务器端模板,但是将两者结合起来很快就变得笨拙了。我们最终得到了这样的结果:

在快速路线中:

router.get("/", function(req, res) 
  var webpackStats = require('../../config/webpack-stats.json');
  var reacthtml = React.renderToString(HiwApp());
  var slideshowHtml = React.renderToString(slideshowApp());
  var config = 
    webpackStats: webpackStats,
    reactOutput: reactHtml,
    slideshowHtml: slideshowHtml
  ;
  res.render("how_it_works/howitworks", config);
);

在翡翠中:

body
  .company-logo.center
  #react-main-mount
    != reactOutput
  include ./content_block_1.jade

  include ./content_block_2.jade

  #slideshow-main-mount
    != slideshowHtml

这很脆弱——如果我们想要 jsx 然后是一个玉模板然后更多的 jsx,我们必须确保我们得到正确的顺序。

我的想法是全部使用 jsx。我知道这类事情有 React.renderToStaticMarkup ,但这并不能解决将动态页面与静态页面混合的问题。

最大的问题:如果我们决定使用 jsx 来完成所有这些工作(比如 layout.jsx 包含所有组件),然后调用 React.renderToString(App();,这会对性能造成重大影响吗?如果是这样,有没有更好的方法来轻松组合静态和动态块?

【问题讨论】:

使用 Reacts renderToString 渲染整个文档完全没问题。初始页面加载渲染会受到惩罚,尽管它非常小。考虑到您最有可能构建一个 SP 应用程序,这确实是一个微不足道的问题,因为用户只访问一次初始页面构建。 【参考方案1】:

虽然这可能有点离题:我们坚持使用翡翠模板。

基本上,我们希望在需要时灵活地为站点区域使用非反应 + 通量架构。我们的网站基本上由许多较小的 SP 应用组成:Site、UserAccount、Team 和 Admin。

我们为什么要这样做?

对于没有访问网站所有部分的用户而言,文件大小和开销更小。

如果需要,可以选择“退出” React 和 Flux。

更简单的服务器端身份验证。

【讨论】:

不错。大约。你花了多少时间?您对架构的表现满意吗? 实际上,我们最终实现了 100% 反应构建。用 php 编写的后端 API,通过 JWT 进行身份验证。 很好的答案,我也有同样的问题,你的前 2 个参数也让我想到了。但是:服务器端身份验证与您的模板引擎有什么关系? 更多的是关于应用程序架构,SP 应用程序中的身份验证可能很复杂。尽管自从发表这篇文章以来,React 有很多选项可以简化这一点。【参考方案2】:

我们成功完成的方法是使用React.renderToStaticMarkup() 在服务器上呈现 JSX shell 模板 (Html.jsx),然后将其作为响应发送到每个服务器端快速路由请求,该请求旨在传递一些HTML 到浏览器。 Html.jsx 只是一个包含 html 头信息和 GA 脚本等的外壳。它不应该包含任何布局。

// Html.jsx
render()
  return (
    <html>
      <head>
        // etc.
      </head>
      <body>
        <div
          id="app"
          dangerouslySetInnerHTML=__html: this.props.markup>
        </div>
      </body>
      <script dangerouslySetInnerHTML=__html: this.props.state</script>
      <script>
        // GA Scripts etc.
      </script>
    </html>
  )

记住这完全没问题,甚至建议在为您的应用补水时在服务器上使用dangerouslySetInnerHTML

应该通过基于状态/道具配置的组件层次结构对同构组件进行动态布局。如果您碰巧使用 React Router,那么您的路由器将根据您提供的路由呈现视图处理程序,这意味着您不需要自己管理它。

我们使用这种技术的原因是在架构上将我们的“应用程序”(它是同构的并响应状态的)与我们的服务器端模板外壳分开,后者只是一种交付机制,实际上是样板。我们甚至将 Html.jsx 模板保留在我们应用程序中的所有 express 组件中,并且不要让它与其他同构 React 组件混合。

我发现对于制定 React/同构架构最有用的资源之一是 https://github.com/yahoo/flux-examples/tree/master/react-router,我们从那里窃取了这项技术。

我们探索了将车把集成为未来使用我们产品的客户开发人员的模板引擎的想法,但决定在 JSX 中编写我们自己的 DSL 并使用一些简单的解析例程来解析我们的类似 HTML 的 DSL 并不那么复杂通过在模板开头添加export default(ES6 模块语法)之类的内容,然后将模板导入到渲染组件中,将其导入 JSX。

如果您认为单独的翡翠文件是必不可少的,您当然可以遵循这种思路并使用翡翠编译器来生成模板,然后在其周围添加模块语法。我也注意到了这个项目,虽然我没有愤怒地探索它:https://github.com/jadejs/react-jade。

【讨论】:

我们最终使用 react-router 为所有内容做了类似于您的 html.jsx 的事情。对于所有使用jade而不是react router的东西,我们将其移至jsx,将其挂载在一个节点上,并没有发现对性能的巨大影响。

以上是关于结合 react 和玉的主要内容,如果未能解决你的问题,请参考以下文章

islider结合react的简单实用

结合 React 路由器和 Firebase 函数 api

Redux 和React 结合

React-redux: React.js 和 Redux 架构的结合

如何结合 Formik 使用 React NumberFormat 包?

结合 React useContext 和一次性数据加载(React hooks)的最佳实践?