Intro
客户端应用程序开发的另一波发展浪潮即将到来. 它涉及ES6, JavaScript的新版本, 通用应用程序, 函数式编程, 服务器端渲染和webpack, 就像一个带着喷气背包的任务执行者.
此外,React现在非常热门. 它是构建高性能组件的一个简洁而优秀的框架. 因为我们已经有了这些, 你怎样才能找到缺失的那一块——能够接受它并为你构建最先进软件的工程师?
React彻底改变了我们对应用程序的看法
反应很明显
重要的事情先做. 在React仅仅作为一个视图库进行营销的背景下, 由于客户端应用程序不仅仅由视图组成, React不会是你的候选人会使用的唯一工具. 不过,这是一个至关重要的问题. 以下是一些筛选问题.
问:React中的高阶组件是什么?
一般来说,高阶组件是一个包装器. 它是一个以组件为参数并返回一个新组件的函数. 它可用于扩展或修改所包含组件的行为(包括呈现的输出). 在不修改React中的底层类的情况下改变行为的组件的使用很好地体现在装饰器模式中.
高阶组件是使用组合构建组件的一种方式. 一个示例用例是抽象出代码片段, 对于多个组件来说是通用的:
Player.js
从React中导入React, {Component, PropTypes};
导出默认类Player扩展组件{
static propTypes = {
黑色:proptype.bool,
数据:proptype.object,
风格:proptype.object
};
static defaultProps = {
黑色:假的,
data: {
src: null,
caption: ''
},
styles: {}
};
render() {
Const{黑色,数据,样式}=这个.props.data;
return (
);
}
}
考虑这个组件,它包含一个 Player
但也包含 module
markup. 该标记可以被其他组件重用. 让我们将其抽象,并允许属性的传递:
Player.js
从React中导入React, {Component, PropTypes};
导入模块容器./ ModuleContainer”;
导出类PlayerInline扩展组件{
static propTypes = {
数据:proptype.object
};
static defaultProps = {
data: {
src: null,
caption: ''
}
};
render() {
Const {src,标题}=这个.props.data;
return (
);
}
}
const Player = new ModuleContainer(Player);
导出默认播放器;
ModuleContainer.js
从React中导入React, {Component, PropTypes};
Module container (Module) {
返回类扩展组件{
static propTypes = {
黑色:proptype.bool,
风格:proptype.object
};
render() {
Const{黑色,样式}=这个.Props // eslint-disable-lint
return (
);
}
};
}
现在我们仍然可以使用前面的实例化方式 Player
,这里没有变化. 如果我们愿意,我们也可以使用内联播放器. 然后,模块包装器标记和props可以与其他模块一起使用:
高阶组件是对ES6中React不再使用混合的设计决策的直接回应, 哪一个是在2015年初完成的. In fact, 高阶组件使结构更清晰, 而且它们更容易维护,因为它们是分层的, 然而,由于结构平坦,混合器有更大的冲突机会.
想了解更多,请点击 另一个高阶组件的用例,重点是消息传递道具. 也可以查看 高阶组件优于混合组件的介绍, 由丹·阿布拉莫夫概述, Redux的作者, and an 本·纳德尔使用refs的高级构图的有趣例子.
问:应该依赖哪些组件 state
, and why?
考虑到关注点的分离,将表示与逻辑分离似乎是明智的. 在React的世界里,一切都是组件. 但是,用于呈现数据的组件不应该必须从API获取数据. 惯例是要有 表象的 (哑)组件无状态,和 container 依赖于状态的组件.
也就是说,惯例并不严格. React中也有不止一种状态类型. 尽管众说纷纭, 在表示组件,特别是交互式组件中使用局部状态似乎并不是一个坏的做法.
另一个区别是组件类和无状态函数组件之间的区别. 显然,后者没有状态. 说到无状态函数组件, 官方建议尽可能使用它们.
问:什么是JSX? 它是如何工作的,为什么要使用它?
JSX是React JavaScript的语法糖, 这使得编写组件变得容易,因为它具有类似xml的语法. 然而,JSX是JavaScript而不是HTML, React将JSX语法转换为纯JavaScript.
乍一看,它看起来很笨拙,尽管许多熟练的开发人员现在已经习惯了. 使用它的主要原因是简单. 定义即使是稍微复杂的结构,最终也会呈现为HTML,这可能是令人生畏和重复的:
React.createElement('ul', {className: 'my-list'},
React.createElement('li', {className: 'list-element'},
React.createElement('a', {className: 'list-anchor', href: 'http://google . '.com'}, '总而言之.com'),
React.createElement('span', {className: 'list-text'}, '欢迎加入网络')
),
React.createElement('li', {className: 'list-element'},
React.createElement('div', {className: 'list-item-content'},
React.createElement(someecustomelement, {data: elementData})
)
)
);
Versus:
考虑更复杂的元素导航组件,有多个嵌套. 简洁是大多数框架都有模板引擎的原因之一,而React有JSX.
要了解更多信息,请点击 在容器组件上下文中对JSX进行了有影响力的讨论.
前端开发的新方法
ES6 (ECMA Script 2015), JavaScript的新版本,已经发布了一段时间. 开源社区中的大多数React材料都使用ES6,有时甚至是ES7. 新版本增加了JavaScript的表现力,并修复了该语言的一些问题. 目前的标准程序是使用 Babel,用于将ES6编译为ES5. 它允许我们用ES6编写代码, 并让它以ES5的形式在大多数当前浏览器上正确执行. 因此,你要雇佣的开发人员精通ES6是至关重要的.
问:ES6的函数有哪些新特性?
实际上有一些. 最突出的是箭头函数表达式, 这是编写匿名函数表达式的一种简洁方式:
var counterArrow = counter => counter++;
// equivalent to function (counter) { return counter++; }
这是一个显著的区别. 用箭头函数 this
对象捕获封闭作用域的值. 所以没有必要再写了 Var that = this
.
另一个不同之处在于参数的定义或传入方式. ES6带来了默认参数和rest参数. 当调用中没有提供参数的默认值时,默认参数是一种非常有用的设置参数默认值的方法. 其余参数, 它们的语法与展开运算符相似, 允许以优雅的方式处理传递给函数的不确定数量的参数.
var businessLogic = (product, price = 1, ...rest) => {
product.Price =价格;
product.细节=休息.map(detail => detail);
};
问:ES6和React中有哪些类?
ES6类提供了创建对象的方法,实际上仍然依赖于原型继承. 它们大多是语法上的糖,但非常方便. 但是,React类不需要它们.
React类是组件. 它们可以用三种方式定义:使用 React.createClass ()
方法,使用ES6类,或者使用函数来创建无状态函数组件:
const Counter1 = React.createClass ({
proptype: {
数:proptype.number
}
defaultProps: {
count: 0
}
渲染:函数(){
return Count: {this.props.count};
}
});
类Counter2扩展组件{
static propTypes = {
数:proptype.number
}
static defaultProps = {
count: 0
}
render() {
return Count: {this.props.count};
}
}
Counter3(props) {
return Count: {props.count};
}
Counter3.propTypes = {
数:proptype.number
};
Counter3.defaultProps = {
count: 0
};
如前所述,建议尽可能使用无状态功能组件. 然而,这些组件尚未针对性能进行优化. 考虑以下GitHub问题在Redux和 React 了解更多.
问:什么是本地样式,或者内联样式,web开发中样式的新趋势?
这个很酷. 到目前为止,声明式CSS总是共享一个全局作用域. 要向可重用组件添加样式,开发人员必须仔细选择名称空间. 另一件事, 有时使用CSS是很困难的, 因为有些风格需要计算, 所以单一的风格成为了一个例外. 当然有 calc()
,但这并不总是足够的.
当地的风格,有时也被称为 内联样式,解决这两个问题. 现在可以将样式表绑定到组件,并且知道它们相对于其作用域保持本地. 这些样式不会影响其作用域之外的元素. 如果这还不够,这些样式在JavaScript中也很容易获得.
AlertWidget.scss
.alertWidget {
字体参数:斜体;
边框:1px实红色;
填充:13 px;
}
.alert {
粗细:700;
color: red;
}
AlertWidget.js
import React, {PropTypes} from ' React ';
AlertWidget(props) {
Const styles = require('./ AlertWidget.scss');
return (
{props.alert}
{props.text}
);
}
AlertWidget.propTypes = {
警告:proptype.text,
文字:proptype.text
};
导出默认AlertWidget;
并非所有的样式都必须是本地的,但它确实是一个非常强大的工具. 要了解更多信息,请点击 对当地风格有影响的介绍 and 在css技巧上讨论内联样式的优缺点
如何陈述?
包含多个组件的应用程序, 特别是大型应用程序, 仅使用局部组件状态是否难以维护. 在React中添加控制器风格以外的逻辑也是一种不好的做法. 但是不用担心,已经有解决方案了.
问:React中的应用程序状态是什么,什么控制着状态?
答案很简单——它是一个对象,它表示应用程序的当前数据集和其他属性. 应用程序状态与组件本地状态的不同之处在于,它可以被多个组件引用.
另一个区别是不应该直接更改应用程序状态. 唯一可以更新它的地方是商店. 存储控制应用程序状态, 还定义可以被分派的动作, 比如用户交互的结果.
大多数React组件不应该依赖于应用范围. 表示组件应该能够访问数据片段, 但是这些数据应该通过属性提供给他们. In React, 惯例是只有容器元素调度操作并引用应用程序范围.
问:那么,在React中有哪些管理状态的工具呢?
在用React构建的应用程序中处理应用程序状态通常是在React之外完成的. Facebook, 是谁给我们带来了React, 还介绍了Flux架构和它的实现. 客户端应用程序的Flux部分是前端业务逻辑发生的地方.
React和Flux没有紧密耦合. Flux的实现也不止一个. 事实上,有很多,还有其他受Flux启发的非常受欢迎的. 最流行的Flux实现是Facebook Flux、Reflux和Alt.js. 还有基于Flux原理的Redux,很多人认为它是在Flux的基础上改进的.
这些库都可以完成工作. 然而,开发者必须做出选择,而且必须有意识地做出选择. 做出选择的一些合理标准:
- 这个存储库有多流行? 查找GitHub星星和分叉数.
- 框架是否得到维护?? 检查在过去两周内完成了多少提交. 此外,阅读作者的笔记和开放和关闭的问题计数.
- 文档的状态是什么? 这一点尤其重要, 团队成员可以增加或更改,但软件的代码库需要清晰.
- 开发人员对特定框架的了解程度如何?
在撰写本文时,Redux是迄今为止最流行的一种. Flux的作者也对它进行了审查,他们认为这是一项出色的工作. 文档是优秀的,有30个免费的短视频教程课程的作者. 框架本身非常简单,并且最符合函数式编程范式.
Alt.Js也有一个充满活力的社区, 在许多文章中受到高度赞扬, 并且有很好的文档. Alt.js也是一个纯Flux实现. 为了支持上述两个实现,放弃了其他几个实现.
这是Redux的作者Dan Abramov写的一篇关于Flux不同实现的文章
问:什么是单向数据流? 它带来了什么好处?
单向数据流构成了对应用程序状态的所有更改都以相同的通用方式完成. 这个流程在Flux实现和Redux中遵循类似的模式. 模式从一个动作开始, 哪个由存储分派和处理,并具有更新状态的效果, 这反过来会导致更新的视图.
通过遵循这种模式, 使用Flux或Redux管理其状态的应用程序是可预测和规范化的. 每个状态版本都是调用一组操作的结果. 这意味着现在可以更容易地通过监视哪些操作被调度来重现每个用户体验. 下面是一个有用的例子 关于在Auth0上使用Flux记录和重放用户操作的文章.
它在调试时也非常有用. In fact, 受Flux启发的最流行的框架之一, Redux, 是创建一套依赖于Flux概念的新开发工具的副作用吗. 有一个演讲,叫做 丹·阿布拉莫夫(Dan Abramov)的《欧博体育app下载》(Hot Reloading with Time Travel).
杂项
编程有很多方法,软件工程也有很多方法. 编程范例的差异远远超出了风格. 最近,有很多人提到JavaScript中的函数式编程. 有许多优势等待着寻求拥抱它的开发人员.
问:解释函数式编程范式.
函数式编程是一种范式,它强调:
- 编写纯函数.
- 没有一个全球性的状态.
- 不改变数据.
- 与高阶函数的复合.
纯函数不会产生副作用, 它们也是幂等的, 这意味着当给定相同的参数时,它们总是返回相同的值.
依赖函数式编程的程序有两个主要优点. 它们很容易理解,也很容易测试. In contrast, 将变量赋值到全局作用域, 依赖事件, 数据的变化很容易使应用程序变得混乱. 从JavaScript开发人员的角度来看, 我甚至会说,这很容易导致代码难以理解,容易出错.
JavaScript并不是严格意义上的函数式语言. However, 具有一等公民的功能, 这意味着它们可以像其他类型一样被分配和传递,并且是可组合的, 对于JavaScript开发人员来说,采用函数式编程当然是可能的.
最近有许多文章赞扬这种风格. 然而,似乎最重要的是新工具,它们变得非常流行. 这些工具在不同程度上结合了关键的函数式编程思想, 包括Redux, React的最新更新, 还有像培根这样的人.js.
问:如何在React中倾向于函数式编程?
首先,编写React代码主要集中在编写好的JavaScript代码上. 用JavaScript编写函数式编程的一般方法是保持一致的编程风格, focused on:
- 编写纯函数.
- 保持函数小.
- 总是返回一个值.
- 组合函数(利用高阶函数).
- 从不改变数据.
- 不会产生副作用.
JavaScript中有许多适合函数式编程的工具,其中包括: .map()
, .reduce()
, .filter()
, .concat
. ES6还提供了一些新的特性,比如原生承诺(native promises)或 …spread
operator.
此外,还有一些可用的线索,比如 eslint 特别是结合衬板的配置 Airbnb JavaScript and React风格指南. 还有其他的工具,比如 immutable.js
代码模式如下 低温冷藏的功能,这有助于防止数据突变,这在测试中特别有价值.
React版本0.14引入了无状态功能组件, 从面向对象的编程向函数式编程迈进了哪一步. 这些组件是最小的,应该尽可能使用. 通常,React应用程序中的绝大多数组件都应该是表示的.
使用Redux是函数式编程方向上的又一步. Redux使用函数调用,不像Flux依赖于事件. 所有Redux reducer都是纯函数. Redux从不改变应用程序状态. 相反,reducer总是返回一个新状态.
问:如何测试React应用程序?
最后但并非最不重要的是开发人员的测试方法. 回归问题是挫败感的最终来源. 除了允许开发人员和客户确保应用程序按预期工作之外, 测试是对回归问题的补救措施.
构建持续集成或部署环境,在其中自动测试每个推送的提交, 如果成功部署, 已经成为标准了吗. 它非常容易设置,许多SaaS都提供免费计划. Codeship 例如,它具有良好的集成和免费计划. 另一个很好的例子是 Travis CI 哪一种提供了更稳定和成熟的感觉,并且对开源项目是免费的.
还必须有实际的测试要运行. 通常使用一些框架编写测试. Facebook为React提供了一个测试框架, 它叫做玩笑, 并以流行的茉莉花为原型. 另一个更灵活的行业标准是Mocha, 通常与测试员Karma结合在一起.
React提供了另一个超级特性,testtils. 它们提供了一套完整的工具,专门用于测试组件. 它们创建一个抽象,而不是将组件插入到实际的页面中, 哪一个允许使用单元测试编译和测试组件.
要获得更多关于测试React应用程序的见解,您可以阅读我们的 blog. 我也推荐大家在 egghead.io, 那里有一些关于React的系列, 还有Flux和Redux, 甚至是一个专注于 测试React应用程序.
Conclusion
React为客户端应用程序带来了高性能,并使使用它的项目处于良好的位置. 图书馆被广泛使用,并有一个充满活力的社区. 大多数情况下,转向React还需要包含其他工具来交付完整的应用程序. 有时,它可能需要更全面的技术升级.
众所周知,Web开发和移动应用开发(Android和iOS)的发展速度非常快. 新工具得到普及,变得有价值,并准备在几个月内使用. 这些创新不仅仅包括工具, 并且常常跨到代码风格, 应用程序结构和系统架构. 前端开发人员需要构建可靠的软件并优化流程. 最优秀的人思想开明,能自信地提出合理的论点. Toptal工程师 还能领导敏捷开发团队吗, projects, 开发过程, 并为产品的效益引进新技术.