In this part, we’ll talk about React’s transactions.
The series
- part one: basic rendering
- part two: componentWillMount and componentDidMount
- part three: basic updating
- part four: setState
- part five: transactions <- you are here
全部译文:
- 第一部分:基础渲染
- 第二部分:componentWillMount and componentDidMount
- 第三部分:基本更新
- 第四部分:setState
- 第五部分:事务 <- 当前位置
transactions everywhere
At this point, the little React clone we built, Feact, is complete. You can see the final version of it here.
到了这里,我们所构建的一个小小的 React 克隆 Feact 已经完成。你可以在这里看到它的最终版本。
But if you decide to dive into React’s source, you’ll quickly notice all these “transactions” everywhere. They obscure the intent of the code, and make it harder to get a sense of what is going on. Rest assured, Feact is following React pretty closely (well, React 15.3 at least), but it purposely doesn’t have transactions to make the actual “meat” of the code more apparent.
但是,如果您深入查看 React 的源代码,您将很快注意到所有这些 “transactions ” 到处都有。它们掩盖了代码的意图,使得更难了解发生了什么。放心,Feact跟随React相当紧密(好吧,至少是 React 15.3),但它没有transactions ,使代码的实际“肉”更明显。
what is a transaction?
The good news is transactions are simple. They are just a pattern the React team has adopted to make the framework more robust and easier to maintain.
好消息是transactions 很简单。它们只是 React 团队采用的一种模式,使框架更加健壮,更易于维护。
Whenever React decides it needs to do something, that “something” usually needs to do a little bit of prep work before, do its main logic, then some clean up work afterwards. This diagram showing how transactions work is taken straight from the React source code
每当 React 决定需要做某事时,这些“某事”通常需要做一些准备工作,执行主要逻辑,然后再执行一些清理工作。这个图是直接从 React 源代码中获取的,展示了 transactions 是如何工作的。
* wrappers (injected at creation time) |
If Feact was to add transactions, its (very) simple take would be something like this:
如果 Feact 添加 transactions ,它(非常)简单的实现将是这样的:
class Transaction { |
一个 transactions 的用例(A use case for transactions)
Why all the fuss? Mostly transactions enable React to do what it needs to do while keeping the browser happy.
为什么大惊小怪?大部分 transactions 确保 React 能够在保持浏览器开放的同时做必要的事情。
For example, consider this dumb little React app, it swaps a button and a text input every 5 seconds
例如,看这个愚蠢的小 React 应用程序,它每5秒交换一个按钮和一个文本输入框的位置:
const MyComp = React.createClass({ |
The trouble with this app is the input element. Whenever you move an input element in the DOM (for example, parentElement.insertBefore(myInputElement, someOtherChild)
), the browser clears out its selection. So if the user has highlighted some text in the input, then something about how your app renders causes React to move the input in the DOM, that selection gets cleared, frustrating your user. To solve this problem, React component updates are done in a transaction. During the initialize phase of the transaction, React grabs the current selection state of the browser and stores it. Then in the close phase, it takes that previous value and makes sure it gets restored. The transactions that happen during a React render handle many other things such as maintaining the window’s scroll position, and a lot of other necessary book keeping. Another benefit of the transaction pattern is it becomes easy to store the state of the browser, do a whole bunch of work, then restore the state at the very end, rather than having to continually worry about accidentally scrolling the window or clearing an input selection.
这个应用程序的麻烦是 input 元素。无论何时在DOM中移动输入元素(例如,parentElement.insertBefore(myInputElement, someOtherChild)
),浏览器将清除其选择状态。因此,如果用户突出选中了输入的某些文本,那么有关应用程序渲染原因导致在 DOM 中移动输入元素,该选择状态将被清除,从而使您的用户感到沮丧。为了解决这个问题,React 组件更新是在 transaction 中完成的。在 transaction 的初始化阶段,React 抓住浏览器的当前选择状态并将其存储起来。然后在关闭阶段,它需要先前的值,并确保它恢复。在 React 渲染期间发生的 transaction 处理许多其他事情,例如维护窗口的滚动位置,以及许多其他必要的状态。transactions 模式的另一个好处是容易存储浏览器的状态,做一大堆工作,然后在最后恢复状态,而不必担心意外滚动窗口或清除输入选择。
Feact transactions
If Feact managed selection using transactions, it’d look something like
如果 Feact 使用 transactions 来管理选择状态,那么看起来就像这样:
const SELECTION_RESTORATION = { |
As always with Feact, trying to keep the code as straightforward as possible. This silly little transaction doesn’t even check if the element is capable of having a selection, amongst many other problems. I don’t recommend using Feact in production.
和Feact一样,尽量保持代码尽可能简单。这个愚蠢的小 transactions 甚至没有检查元素是否能够进行选择,以及许多其他问题。我不建议在生产中使用Feact。
Over in React, transactions are more complicated. For starters, they allow more than one wrapper. They also deal with exceptions being thrown, and ensure transactions don’t call back into themselves.
在 React 中,transactions 更复杂。对于初学者,它们允许多个包装。他们还处理抛出的异常,并确保 transaction 不会自动回调。
系列总结(Series Conclusion)
And with that, this series has covered the basics of how React works. Whenever you’re debugging your React applications, that large chunk of the call stack that is inside React should feel a little less alien now. That’s a primary reason I decided to write this series out.
与此同时,本系列还介绍了 React 的基本工作原理。无论何时调试您的 React 应用程序,现在应该会感觉到 React 内部的大块调用堆栈有一点了解。这是我决定写这个系列的主要原因。
If you spotted any errors or have any feedkback, feel free to email me.