Adding createElement.
This commit is contained in:
@@ -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
|
entire process. The more black-boxes we have in our mental model the
|
||||||
harder it will be for us to diagnose performance problems.
|
harder it will be for us to diagnose performance problems.
|
||||||
|
|
||||||
*** ~JSX~
|
** ~JSX~
|
||||||
|
|
||||||
But before we get to ~createElement~ we should talk about JSX. While
|
But before we get to ~createElement~ we should talk about JSX. While
|
||||||
not strictly a part of React it is almost universally used with
|
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
|
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
|
#+BEGIN_SRC javascript
|
||||||
function createElement(node) {
|
{
|
||||||
if (typeof node === 'string') {
|
type: NODE_TYPE,
|
||||||
return {
|
props: {
|
||||||
type: 'TEXT_ELEMENT'
|
propA: VALUE,
|
||||||
|
propB: VALUE,
|
||||||
|
...
|
||||||
|
children: STRING | ARRAY
|
||||||
}
|
}
|
||||||
const [ tag, props, children ] = node;
|
|
||||||
const element = document.createDOMElement(tag);
|
|
||||||
for ([key, val] in props) {
|
|
||||||
element[key] = val;
|
|
||||||
}
|
|
||||||
children.forEach(createElement);
|
|
||||||
}
|
}
|
||||||
#+END_SRC
|
#+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) {
|
||||||
|
// an array: not text, number, or other primitive
|
||||||
|
if (typeof node === 'object') {
|
||||||
|
const [ tag, props, children ] = node;
|
||||||
|
return {
|
||||||
|
type: tag,
|
||||||
|
props: {
|
||||||
|
...props,
|
||||||
|
children: children.map(createElement)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// primitives like text or number
|
||||||
|
return {
|
||||||
|
type: 'TEXT',
|
||||||
|
props: {
|
||||||
|
nodeValue: node,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#+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
|
* Rendering Model
|
||||||
React calls shouldComponentUpdate to know if it should re-render the
|
React calls shouldComponentUpdate to know if it should re-render the
|
||||||
component. by default it returns true.
|
component. by default it returns true.
|
||||||
@@ -267,6 +317,7 @@ function createElement(node) {
|
|||||||
* Concurrent Rendering
|
* Concurrent Rendering
|
||||||
* UX
|
* UX
|
||||||
* JS Service Workers
|
* JS Service Workers
|
||||||
|
* Keys
|
||||||
* Reconciliation
|
* Reconciliation
|
||||||
- diffing algorithm based on heuristics. generic algorithm is O(n^3)
|
- diffing algorithm based on heuristics. generic algorithm is O(n^3)
|
||||||
- "Fiber" algorithm notes
|
- "Fiber" algorithm notes
|
||||||
|
|||||||
Reference in New Issue
Block a user