Adding createElement.

master
Thomas Hintz 4 years ago
parent ed636b090b
commit ecb1d96dc8

@ -115,7 +115,7 @@ understand how it works so that we can have a complete picture of the
entire process. The more black-boxes we have in our mental model the
harder it will be for us to diagnose performance problems.
*** ~JSX~
** ~JSX~
But before we get to ~createElement~ we should talk about JSX. While
not strictly a part of React it is almost universally used with
@ -226,25 +226,75 @@ So now that we've worked through JSX we're ready to tackle
TODO JSX also does validation and escapes input to prevent XXS
*** ~createElement~
** ~createElement~
A tale of two trees.
React expects nodes defined as Javascript objects that look like this:
#+BEGIN_SRC javascript
{
type: NODE_TYPE,
props: {
propA: VALUE,
propB: VALUE,
...
children: STRING | ARRAY
}
}
#+END_SRC
That is an object with two properties: ~type~ and ~props~. The ~props~
property contains all the properties of the node. The node's
~children~ are also considered part of its properties. The full
React's ~createElement~ includes more properties but they are unlikely
to be relevant to your application's performance or our version of
React here.
#+BEGIN_SRC javascript
// React's createElement
const ReactElement = function(type, key, ref, self, source, owner, props)
#+END_SRC
So all our ~createElement~ needs to do is transform our data structure
into the objects that our React expects.
#+BEGIN_SRC javascript
function createElement(node) {
if (typeof node === 'string') {
// an array: not text, number, or other primitive
if (typeof node === 'object') {
const [ tag, props, children ] = node;
return {
type: 'TEXT_ELEMENT'
type: tag,
props: {
...props,
children: children.map(createElement)
}
const [ tag, props, children ] = node;
const element = document.createDOMElement(tag);
for ([key, val] in props) {
element[key] = val;
};
}
// primitives like text or number
return {
type: 'TEXT',
props: {
nodeValue: node,
children: []
}
children.forEach(createElement);
};
}
#+END_SRC
Our ~createElement~ has two main parts: complex elements and primitive
elements. The first part tests whether ~node~ is a complex node
(specified by an array) and then generates an ~element~ object based
on the input node. It recursively calls ~createElement~ to generate an
array of children elements. If the node is not complex then we
generate an element of type 'TEXT' which we use for all primitives
like strings and numbers.
That's it. Now we have everything we need to actually begin the
process of rendering our tree to the DOM!
*** Reconciliation
A tale of two trees.
* Rendering Model
React calls shouldComponentUpdate to know if it should re-render the
component. by default it returns true.
@ -267,6 +317,7 @@ function createElement(node) {
* Concurrent Rendering
* UX
* JS Service Workers
* Keys
* Reconciliation
- diffing algorithm based on heuristics. generic algorithm is O(n^3)
- "Fiber" algorithm notes

Loading…
Cancel
Save