@qinyun
2018-09-02T15:47:50.000000Z
字数 2159
阅读 1247
未分类
昨天,React开发者、Redux 和 Create React App 作者之一的Dan Abramov gaearon在GitHub上的React issue 上宣布了一个名为 React Fire的项目,他表示这个项目旨在使React DOM更现代化,目标是让React可以更好地与DOM的工作方式保持一致,React团队会重新审视之前做出的一些有争议的决策,并让React变得更小更快。
他表示,今年以来,React团队主要关注的是React的基础改进(https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html),目前这项工作已经接近尾声。接下来,他们开始考虑React DOM的下一个主要版本应该是什么样子的。
由于现在存在相当多的问题,如果不对内部做一些大手术,有些问题很难甚至无法解决。所以他们希望能够撤销过去犯下的一些错误,这些错误导致了无穷无尽的后续修复和大量的技术债务。他们还希望删除事件系统中的一些抽象,这些抽象从React诞生之日起就几乎没有被动过,它们也是造成复杂性和臃肿的库文件的罪恶之源。这项行动称为“React Fire”。
React团队可能会在当前的计划中添加或删除一些内容,但总体是这样考虑的:
停止在value属性上反映输入值。这个特性最初是在React 15.2.0中添加的。这是一个非常普遍的需求,因为人们对DOM模型的理解就是在DOM检查器中看到的value应该与值JSX的value属性相匹配。但DOM其实不是这样的,在输入字段时,浏览器并不会更新value属性,所以React也不应该这样做。事实证明,这个变化虽然可能对依赖CSS选择器的一些代码有点用处,但却导致了一系列错误——其中一些仍未得到修复。从这一点上说,显然不值得继续与浏览器作斗争,所以应该回退。
将事件附加到React root,而不是document。在将React应用程序嵌入到更大的系统时,将事件处理器附加到document会成为一个问题。Atom编辑器是最早遇到这种情况的案例之一。大型网站通常会出现非常复杂的边缘案例,通过stopPropagation与非React代码发生交互或进行跨React root交互。他们还希望能够尽早将事件附加到每个root,这样就可以在更新期间减少运行时检查。
从onChange切换到onInput,并且不需要为不受控组件进行polyfill。 React在DOM中使用了一个不同的事件名来表示input事件,这无疑让人感到有些困惑。虽然通常应该避免在没有得到显著好处的情况下做出这样的大变更,但我们还是希望能够因此消除一些复杂性。因此,将这两个变更结合在一起是有意义的,并借此机会让onInput和onChange与DOM事件在不受控组件上的行为保持一致。
大幅简化事件系统。当前的事件系统自2013年初始实现以来,几乎没有发生任何变化。它在React DOM和React Native中被重复使用,因此它没有必要是抽象的。它提供的很多polyfill对于现代浏览器来说是不必要的,并且其中一些产生的问题比它们解决的问题还要多。它也占了React DOM包大小的很大一部分。Dan表示,现在还没有非常具体的计划,但有可能会完全将事件系统fork出去。完全摆脱合成事件似乎是合理的,我们应该停止使用冒泡事件(比如媒体事件,它们不会在DOM中冒泡,而且也没有充分的理由进行冒泡)。React团队希望保留一些特定于React的功能,例如跨门户的冒泡,但他们将尝试通过更简单的方法(例如重新分配事件)来实现。
className改为class。这个提案已经被提了无数次了。在React 16中, 允许将class传给DOM节点。但避免语法限制所带来的好处无法抵消它所造成的混乱,他们不会单独做出这个变更,需要与上述的结合在一起才有意义。不能在没有给出警告的前提下让二者同时存在,因为组件生态系统很难处理好它们。每个组件都需要学会如何正确处理它们,还要冒着出现冲突的风险。
Dan表示,如果继续为React Native Web等项目公开当前的私有React事件系统API,他们就无法做出这些变更。不过,React Native Web需要一个不同的策略,因为React Fabric可能会将更多的响应者系统移到Native端。
所以,React团队可能需要放弃与某些旧版浏览器的兼容性,或者需要提供更多独立的polyfill。不过,他们仍希望能够支持IE11,但可能不会试图消除现有浏览器的一些差异——这也是很多现代UI库所采取的立场。
在这个阶段,这个项目非常具有探索性。React团队不确定上述的所有事情是否能够奏效。他们会在Facebook内部进行实验,并以渐进的方式逐步实现。可能还需要引入一个功能标志,fork出一些代码,并让Facebook的一小部分人先试用新功能。16.x开源版本将保留旧有的行为,但在master上,可以通过功能标志开启新功能。