source code reading started
UI updating, in its essential, is data change. React offers a straightforward and intuitive way to program front-end Apps as most moving parts are converged in the form of states, and most UI tasks can be done with a single …, I mean, a single method, setState(). In this article, we are going unfold the setState() implementation, and peek inside the diffing algorithm by mutating an individual DOM element.
Last time we discussed the core Transaction class and ReactDefaultBatchingStrategyTransaction. The instantiation is not the sole Transaction involved in UI updating but merely the one that leads. In this post, we are going to examine the other Transactions which, together with ReactDefaultBatchingStrategyTransaction, outline the UI updating processing logic.
To some extent, the sophisticated and efficient UI updating is what makes React React. But before we dive into the well-known mechanisms (virtual DOM and diffing algorithm) that empower the UI updating, we need to understand Transaction which transfers the control from the high-level API setState() to those underlying processing logic.
Last time we completed the upper half of the class component rendering logic which is similar to albeit different from simple component rendering in the following respects: 1) it instantiates one additional ReactCompositeComponent to represent the class component (App); and 2) it calls App.render() that triggers cascading React.createElement()s to establish a ReactElement tree. This time we are going to explore more branches in lower half by examining how the ReactElements in the tree is transformed to their respective ReactDOMComponents, and eventually, to real DOM objects.
Last time we completed the platform agnostic logic (a.k.a., upper half) that embeds ReactElement into ReactCompositeComponent[T] and then uses it to derive ReactDOMComponent[ins]. This time I will discuss how a renderable HTML DOM element is created with ReactDOMComponent[ins], and complete the JSX-to-UI process.
UI updating, in its essential, is data change. React offers a straightforward and intuitive approach to front-end program with all the moving parts converged in the form of states. Code review is also made easier to me as I like to start with data structures for a rough expectation of the functionalities and processing logic. From time to time, I was curious about how React works internally, hence this article. It never hurts to have a deeper understanding down the stack, as it gives me more freedom when I need a new feature, more confidence when I want to contribute and more comfort when I upgrade.
Objects life-cycle is crucial. A mistake in determining an object’s lifecycle can lead to resource (e.g., memory, fd) leaks as the resource owned cannot be properly released and recycled for future use. When the leak accumulates to a certain level, it crashes the whole system. Objects life-cycle is also complicated since the ownership of one object might be relinquished by, transferred to, or shared with different entities which include but are not limited to variables, function arguments, modules, data structures, containers, and threads. Again, the resource has to be released and recycled by one of the owners at some undetermined point. There is no de-facto standard to determine objects life-cycle. Utilities like GC (garbage collection) that is used in Java, ARC used in Objective-C and all those pointers (ptrs) in C++, all have their pros and cons. However, this article is not about pros and cons but is focused on C++ resource management helper classes, Smart Pointer, shared_ptr, auto_ptr and unique_ptr.