我们写这篇文章的目的是为了让你对React有一个更好的认知,什么能做和什么不能做以及React的设计理念
虽然我们很乐意看到社区的贡献,但是我们也不希望悠然违反一些原则。
注意:这篇文章是假设你对React有一个很深的理解,它描述了React的设计原则,而不是React组件及程序
对React的简介请阅读Thinking in React
组成
React的主要特性是组建的组成,不同人编写的组件可以一起更好的工作,你可以给一个组件添加功能而不会影响整个代码库的更改.
比如:在一个组件中引入一些本地state而不会对使用它的组件造成影响。同样,如果有必要可以添加初始化以及拆卸的代码到任何组件中。
在组建中使用state或生命周期挂钩也不是坏的,比如一些功能强大的特性,它们应该有节制的使用,但是我们没有移除它们的打算,相反的,
我们认为他们是使得的React更有用的组成部分。我们将来会使更多的功能模式
但是,本地state和生命周期挂钩将为该模型的一部分。
组件经常被描述为’just functions’,但是在我们的视角中,他们需要变得更加有用,在React中,组件描述了任何组成的行为,包括rendering
生命周期,以及state,一些外部的库,像Relay增加组件了其他的责任,比如描述data依赖。
Common Abstraction(通用的抽象)
通常情况下我们抵制在用户级就可以实现的行为,我们不想用无用的库膨胀你的应用,但是也有些例外,比如:如果React对本地state和生命周期
挂钩不提供支持,用户会创建通用抽象给他们,当有多个抽象竞争时React不能充分利用他们的属性执行,它不得不以最低的标准工作。这也是为什么
我们有时会给React添加一些特性,如果我们注意到许多组件不兼容或低效的执行某些功能,我们可能更愿意考到React。我们不会轻易的干这件事。
当我们做它时,因为我们有信心提高抽象层次使整个生态系统受益。state,生命周期挂钩跨浏览器事件正常化是个很好的例子。我们经常与社区讨论
改善建议,你可以在big picture中找到这些讨论
Escape Hatches(逃生舱口)
React是实用主义的,它是由写Facebook的产品需求而驱动的,虽然它受一些范例的影响,但也不是完全主流。比如,函数式编程,对不同技能的开发
保持可访问是项目的一个明确的目标。如果我们想反对一个我们不喜欢的模式,在反对它之前我们考虑所有存在的场景。如果一些模式对于构建app和有用
但是很难表达,我们会为它提供必要的API。
Stability(稳定性)
我们重视API的稳定性,Facebook有两万个组件在使用React,这也是我们为什么通常不愿意改变公共API或行为。但是”nothing changes”稳定性的意义有点被
高估了,它迅速停滞了。相反,我们更喜欢”在生产环境大量使用并且一些东西变化时有一个明确的迁移路径”的稳定意义。当我们反对一种形式时,我们在Facebook研究
它的内部使用并添加反对警告。这让我们评估改变的重大影响。有时,我们发现它太简单的话我们会退出,并且我们需要战略性的思考关于这次改动代码库的要点是否准备好。
如果我们自行这次的更改不是太具有破坏性并且此次战略性转移对用户场景是可实施的,我们会在社区中释放反对警告。我们会和外部使用React的用户密切联系并且我们会
监视流行的开源项目并指引他们修理这些警告。由于React代码库规模庞大,内部迁移成功是一个很好的指标并且其余公司也不会有问题。
Scheduling(时间表 进度表)
在React中即使你的组件被描述为函数,你也不能直接调用它们。每一个组件返回一个需要渲染什么的描述
并且这个描述包括用户自定义组件及主机组件。通过组件的递归得到render结果去更改UI树。这是一个不明显但是很强大的区别,因为你不会调用组件函数但是让React自己调用.
这意味着如果有必要React有权延迟调用它。在当下的实现中,在单个刻度期间,React递归的走着树并调用所有的要修改的树的render函数。在反应的设计中这是一个共同的主题,
一些流行的库实现的是”push”方法,当新数据可用时再执行计算。然而React坚持”pull”方法,计算会被推迟,除非有必要。
React不是一个普通的数据处理库,它是用来构建用户界面的。我们认为在app中有独特的优势,因为它知道哪些计算是有意义的哪些没有。如果有些多东西在屏幕外,我们可以
延迟它的数据逻辑处理,如果数据到达的速度快于frame的速度,我们可以批量更新,我们可以优先考虑用户交互的工作(点击button的动画效果)来避免dropping frame,
不太重要的(从网络获取数据)后台工作