如何在已有的 Web 应用中使用 ReactJS
原文: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 。
独立状态 - 这种状态独立存在于 container 元素中。所有按钮、输入框等的交互状态都由这个 wrapper / container 元素分享。
- 共享状态 - 这种状态由多个元素共享。比如,从页面其它位置的日期下拉框中更新日历。 菜单和日历在不同的容器中,但是它们的状态是共享的。
我将用 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 。
所有框架通常都是:
- 挂载到特殊的容器 container上 ( 比如
App中名为#ID的 div)。 - 向容器 container 中渲染内容。
- 负责跟踪和更新容器 container 中的内容。
- 负责移除容器 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 中,通常有两个分享组件状态的方法:
- 将组件包裹在 container 元素中去管理状态,将数据/函数作为 props 向组件传递。
- 使用类似 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的更多相关文章
- 因为此控件已在 web.config 中注册并且与该页位于同一个目录中
在web.config文件配置了用户控件 <pages> <controls> <add tagPrefix="my" tagName="l ...
- 如何在现有的 Web 应用中使用 ReactJS
原文:How to Sprinkle ReactJS into an Existing Web Application 译者:nzbin 当我们学习一项新技术,可能是一个 JavaScript 框架, ...
- SharePoint Framework 在web部件中使用已存在的JavaScript库 - JavaScript库的格式
博客地址:http://blog.csdn.net/FoxDave JavaScript库格式 不同的JavaScript库的编译和打包方式各不相同.一些是以模块的方式打包的,而另一些是以纯脚本运行在 ...
- SharePoint Framework 在web部件中使用已存在的JavaScript库 - 捆绑打包和外部引用
博客地址:http://blog.csdn.net/FoxDave 在构建SPFx客户端web部件时,你可以使用公网已有的JavaScript库来构建强大的解决方案.但是在使用的时候你需要考虑你引用的 ...
- 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入
在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...
- 如何在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 ...
- JAVA WEB项目中各种路径的获取
JAVA WEB项目中各种路径的获取 标签: java webpath文件路径 2014-02-14 15:04 1746人阅读 评论(0) 收藏 举报 分类: JAVA开发(41) 1.可以在s ...
- 如何把Power BI嵌入到Web应用中
(此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:这篇其实不是一个操作向导了,主要对Power BI的嵌入特性进行探讨. Power BI ...
- HTTP学习二:Web应用中的HTTP
1 HTTP连接 1.1 TCP连接对性能的影响 TCP三次握手如下图: 如上图,建立一次TCP连接要经过三个步骤.HTTP是建立在TCP之上的,因此TCP连接的性能直接影响HTTP的性能. TCP影 ...
随机推荐
- 用Scrutor来简化ASP.NET Core的DI注册
目录 背景 Scrutor简介 Scrutor的简单使用 注册接口的实现类 注册类自身 重复注册处理策略 总结 相关文章 背景 在我们编写ASP.NET Core代码的时候,总是离不开依赖注入这东西. ...
- [React] react+redux+router+webpack+antd环境搭建一版
好久之前搭建的一个react执行环境,受历史影响是webpack3.10.0和webpack-dev-server2.7.1的环境,新项目准备用webpack4重新弄弄了,旧的记录就合并发布了(在没有 ...
- SmoOne——开源免费的企业移动OA应用,基于.Net
一.SmoOne是什么一个开源的移动OA应用 二.语言C# 三.开发环境Visual Studio 四.开发平台Smobiler Designer 五.功能该应用开源代码中包含注册.登录.用户信息等基 ...
- PLSQL创建Oracle定时任务
在使用oracle最匹配的工具plsql的时候,如果用plsql创建定时器呢?下面我简单介绍使用工具创建定时器的方法: 1.创建任务执行的存储过程,如名称为YxtestJob,向测试表中插入数据 cr ...
- 杭电ACM2016--数据的交换输出
数据的交换输出 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- 图解HTTP(1)之WEB及网络基础
HTTP协议访问Web 当你在浏览器地址栏中键入有效URL(统一资源定位符)相应的网页页面就会展示出来,那么它是如何展示出来的, 首先这存在两个概念 ------客户端.服务器端 客户端(client ...
- Go中变量作用域的小坑
直接上一实例: package main import "fmt" func main(){ fmt.Println("for start") ; a < ...
- python学习笔记(六)、类
Python与java.c++等都被视为一种面向对象的语言.通过创建自定义类,用于处理各种业务逻辑.面向对象有封装.继承.多态三个特征,这也是面子对象语言的通用特征. 1 封装 封装,是值向外部隐藏内 ...
- Vue开篇之Vue-cli搭建项目
介绍 Vue.js是一套构建用户界面的渐进式框架.Vue 只关注视图层,采用自底向上增量开发的设计.Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. 第一步:安装node ...
- Apex 中 PageReference 的使用
PageReference类的作用 PageReference类位于Apex的System命名空间下.它可以用来在Apex代码中将页面跳转到指定的位置.在开发的时候,我们也可以向其中添加任意的参数. ...