原文:How to Sprinkle ReactJS into an Existing Web Application

译者:nzbin

当我们学习一项新技术,可能是一个 JavaScript 框架,也可能是一个 CSS 方法,我们将面对这样的挑战 如何在旧网站上运用这项新技术?。很多教程讲述了如何从头开始,但却很难运用到实际工作中。

在这篇教程中,我会通过一些很基本的例子讲解如何灵活运用 ReactJS,以及替换使用 jQuery 写的代码。

从 jQuery 到 React

我最近的任务是用 React 重构一个使用 jQuery 写的功能。这个过程困难重重,因为大量的 jQuery 分散在代码段中。使用 jQuery 构建所有的 UI 是可能的(我们已经这样做了很多年),但是在规模变大之后,将变得混乱且难以维护。

无论你使用 Angular, Ember, Vue, React, 或者只是 jQuery,你所做的事情和开发者多年来所做的事情是一样的:

渲染 HTML > 接收用户事件 > 重新渲染 HTML

因为 jQuery 非常依赖选择器比如  .classes#IDs 去控制 DOM,所以大量的属性会使 HTML 变得容易混淆,而这些属性的目的只是方便 jQuery 查找。如果代码量比较小,这是没有问题的, 但是如果代码量庞大,就会很难知道哪些类用于 CSS,哪些类用于 JavaScript。如果你之前为了改变一个功能而在 HTML 模板或 JavaScript 中查找 find 一个 .class 或者 #ID 选择器,你应该明白我说的。

过渡依赖 .classes#IDs 的选择来操纵 HTML 并不轻松。

所以,如果你的代码是用 jQuery 或者其它框架所写,那么应该如何使用 React 去替换这些 UI 片段?

开始之前应该了解的事情

Wrapper / Container 元素

无论使用 jQuery 还是下一个流行框架开发应用,大多数情况都是用一个根元素包裹 UI 片段。如果代码库使用 jQuery,通常会有一个元素充当 wrapper 选择器。使用 jQuery 选择 wrapper 元素,它被用于动态更新 DOM。

<!--
.MyAwesomeFeature acts as a container to select
and manipulate child components with jQuery.
-->
<div class="MyAwesomeFeature">
<div class="MyAwesomeFeature__title"></div>
<div class="MyAwesomeFeature__image"></div>
</div> <script>
var container = $(".MyAwesomeFeature");
$(".MyAwesomeFeature__title", container).text("Hello World!"); // Other DOM changes, event handlers, etc...
</script>

独立状态 vs. 共享状态

可以看一下你的应用中的功能状态是独立 isolated 于 container 元素还是在多个元素中共享 shared

相关教程: Getting Started with React

  1. 独立状态 -  这种状态独立存在于 container 元素中。所有按钮、输入框等的交互状态都由这个 wrapper / container 元素分享。

  2. 共享状态 - 这种状态由多个元素共享。比如,从页面其它位置的日期下拉框中更新日历。 菜单和日历在不同的容器中,但是它们的状态是共享的。

我将用 jQuery 和 ReactJS 做的 4 个例子解释共享/独立状态的概念。

用 jQuery 实现独立状态

假设我们有一个 web 应用,它展示了一个 emoji,当点击按钮,会随机展示一个新的 emoji。下面的代码是一个典型的 jQuery 应用,我们选择父级元素 .mood-container ,然后动态改变内容。

以下是例子 的 HTML:

<!--
Demonstrates how jQuery can be used to
use a container as a selector and update
the content within.
-->
<div id="mood-container">
<div class="Mood">
<div class="Mood__emoji"></div>
<div class="Mood__name">[ Emoji Placeholder ]</div>
<button class="Mood__button">Random Mood</button>
</div>
</div>

See the Pen Isolated state with jQuery by Andrew Del Prete (@andrewdelprete) on CodePen.

这并不是使用 jQuery 更改 DOM 的唯一策略,但很常见。

用 ReactJS 实现独立状态

使用如 React 的库的好处之一就是可以将上面的 JavaScript 和 HTML 封装成一个组件 component 。它是一个更可靠、可维护、可重用的功能部件。

这在处理大型应用时非常有用,因为组件 component 的渲染和更新是同步的。我并不是指将关注点与逻辑和视图层混合在一起,而是如何将 JavaScript 和 HTML 以组件 component 的形式组织代码。这是所有 JavaScript 框架的共同理念,因此被称为 Framework

所有框架通常都是:

  1. 挂载到特殊的容器 container上 ( 比如 App 中名为 #ID 的 div )。
  2. 向容器 container 中渲染内容。
  3. 负责跟踪和更新容器 container 中的内容。
  4. 负责移除容器 container 中的内容。

以下是使用 React 整合后的新的 HTML:

<!--
Demonstrates how ReactJS mounts itself
to a container and takes it from there.
-->
<div id="mood-container" />

See the Pen Isolated state with ReactJS by Andrew Del Prete (@andrewdelprete) on CodePen.

用 jQuery 实现共享状态

使用 jQuery 可以很容易实现,但是,如果一个区域动态影响另一个单独使用选择器的区域时,可能会变得混乱。另外,当你使用 .classes 以及 #IDs 作为选择器手动控制 DOM 的时候,你要负责跟踪所有事情的开销。

See the Pen Shared state with jQuery by Andrew Del Prete (@andrewdelprete) on CodePen.

在这个例子中,我们通过 .Mood__name.Mood__button-name 选择器分享 mood name ,并且通过一个容器中的按钮去更新另一个容器中的 emoji 。这还可以写的更简单一些,但是不管怎样,当尝试用 jQuery 选择器单独管理所有这些事情时,就会变得很糟糕。

用 ReactJS 实现共享状态

在 ReactJS 中,通常有两个分享组件状态的方法:

  1. 将组件包裹在 container 元素中去管理状态,将数据/函数作为 props 向组件传递。
  2. 使用类似 Redux 的工具在全局定义状态和 actions,然后将组件挂载上去。

使用 Container 分享状态

这是使用  React 渲染比较常见的方式,尤其 SPA 应用或者 UI 片段。因为我们希望组件之间通信,所以我们将它们放置在父级组件中,然后向下传递属性来更新每个子组件。这是 ReactJS 最基本的工作方式。

这种方式适用于多个 UI 组件被一个父组件包裹的情况。很多之前创建的应用可能不适合,但是可以根据 UI 布局情况选择使用。

See the Pen Shared state with ReactJS - Container by Andrew Del Prete (@andrewdelprete) on CodePen.

使用 Redux 分享状态

类似 Redux(flux 的另一种实现)的库可以很容易的实现应用中不同组件之间的通信。可以将 actions 和状态属性挂载到组件,通过更新全局对象 Redux 来分享状态。

See the Pen Shared state with ReactJS - Redux by Andrew Del Prete (@andrewdelprete) on CodePen.

总结

我希望这篇文章可以让你更好地了解需要关注的内容以及如何将 ReactJS 运用到现有的应用中。主要的解决方法就是,如果你使用 jQuery 处理 UI 片段,那么你可以将容器元素替换成一个 React 组件。如果你需要在多个组件中分享状态,那么你可以使用容器方法或者类似 Redux 的库。

感谢阅读!

-Andrew Del Prete

如何在已有的 Web 应用中使用 ReactJS的更多相关文章

  1. 因为此控件已在 web.config 中注册并且与该页位于同一个目录中

    在web.config文件配置了用户控件 <pages> <controls> <add tagPrefix="my" tagName="l ...

  2. 如何在现有的 Web 应用中使用 ReactJS

    原文:How to Sprinkle ReactJS into an Existing Web Application 译者:nzbin 当我们学习一项新技术,可能是一个 JavaScript 框架, ...

  3. SharePoint Framework 在web部件中使用已存在的JavaScript库 - JavaScript库的格式

    博客地址:http://blog.csdn.net/FoxDave JavaScript库格式 不同的JavaScript库的编译和打包方式各不相同.一些是以模块的方式打包的,而另一些是以纯脚本运行在 ...

  4. SharePoint Framework 在web部件中使用已存在的JavaScript库 - 捆绑打包和外部引用

    博客地址:http://blog.csdn.net/FoxDave 在构建SPFx客户端web部件时,你可以使用公网已有的JavaScript库来构建强大的解决方案.但是在使用的时候你需要考虑你引用的 ...

  5. 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入

    在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...

  6. 如何在ASP.NET Web站点中统一页面布局[Creating a Consistent Layout in ASP.NET Web Pages(Razor) Sites]

    如何在ASP.NET Web站点中统一页面布局[Creating a Consistent Layout in ASP.NET Web Pages(Razor) Sites] 一.布局页面介绍[Abo ...

  7. JAVA WEB项目中各种路径的获取

    JAVA WEB项目中各种路径的获取 标签: java webpath文件路径 2014-02-14 15:04 1746人阅读 评论(0) 收藏 举报  分类: JAVA开发(41)  1.可以在s ...

  8. 如何把Power BI嵌入到Web应用中

    (此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:这篇其实不是一个操作向导了,主要对Power BI的嵌入特性进行探讨. Power BI ...

  9. HTTP学习二:Web应用中的HTTP

    1 HTTP连接 1.1 TCP连接对性能的影响 TCP三次握手如下图: 如上图,建立一次TCP连接要经过三个步骤.HTTP是建立在TCP之上的,因此TCP连接的性能直接影响HTTP的性能. TCP影 ...

随机推荐

  1. DriverManager 驱动管理器类简介 JDBC简介(三)

    驱动程序管理器是负责管理驱动程序的,驱动注册以后,会保存在DriverManager中的已注册列表中 后续的处理就可以对这个列表进行操作 简言之,驱动管理器,就是字面含义,主要负责就是管理 驱动 概述 ...

  2. React Fiber 数据结构揭秘

    此章节会通过两个 demo 来展示 Stack Reconciler 以及 Fiber Reconciler 的数据结构. 个人博客 首先用代码表示上图节点间的关系.比如 a1 节点下有 b1.b2. ...

  3. 【原创】PicUploader: 一个还不错的图床工具

    PicUploader PicUploader 是一个用php编写的图床工具,它能帮助你快速上传你的图片到云图床,并自动返回Markdown格式链接到剪贴板.配置完成后,要获取一个可用于markdow ...

  4. Flask的请求处理机制

    在Flask的官方文档中是这样介绍Flask的: 对于Web应用,与客户端发送给服务器的数据交互至关重要.在Flask中由全局的request对象来提供这些信息 属性介绍 request.method ...

  5. JavaScript 中,定义函数时用 var foo = function () {} 和 function foo() {}有什么区别?

    对于新手来说(本人也是新手-_-!),好像var foo = function () {} 和 function foo(){}并没有什么区别,意识里可能就认为就是两种不同的写法而已.但是,通过网上查 ...

  6. Mac下如何用SSH连接远程Linux服务器

     终端命令 a).打开Mac的命令终端 b).输入ssh -p 22 root@102.210.86.213 它会提示你输入密码,输入正确的密码之后,你就发现已经登陆成功了.(22: 端口号 root ...

  7. Linux 安装composer

    wget https://getcomposer.org/installer //下载一个脚本文件 php installer //php执行下这个php脚本(虚拟机我没装环境.以下截图有操作流程) ...

  8. 如何在idea中调试spring bean

    步骤 在 Run/Debug Confihuration 中,增加 Application -> local,除去其余配置外,在 Program arguments 一栏添加以下字段:javac ...

  9. vue element-ui 2.3.4版本 input number值为0时 显示不出来

    解决:官方修复了这个bug.升级element-ui为2.3.5版本就好了

  10. Dynamics 365 Customer Engagement V9 活动源功能报错的解决方法

    微软动态CRM专家罗勇 ,回复300或者20190120可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 安装好Dynamic ...