Last active
August 14, 2019 17:24
-
-
Save Tevinthuku/303aaff6412b31dbdece2202dde0dd7c to your computer and use it in GitHub Desktop.
reconciling children
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// .. code | |
const PLACEMENT = "PLACEMENT"; // this is for a child that needs to be added | |
const DELETION = "DELETION"; //for a child that needs to be deleted. | |
const UPDATE = "UPDATE"; // for a child that needs to be updated. refresh the props | |
function createArrayOfChildren(children) { | |
// we can pass children as an array now in the call to render | |
/** | |
* render () { | |
return [ | |
<div>First</div>, | |
<div>Second</div> | |
] | |
} | |
*/ | |
return !children ? [] : Array.isArray(children) ? children : [children]; | |
} | |
function reconcileChildrenArray(wipFiber, newChildElements) { | |
const elements = createArrayOfChildren(newChildElements); | |
let index = 0; | |
// let the oldFiber point to the fiber thats been rendered in the | |
// dom if its present. if its initialRender then return null. | |
let oldFiber = wipFiber.alternate ? wipFiber.alternate.child : null; | |
let newFiber = null; | |
while (index < elements.length || oldFiber != null) { | |
const prevFiber = newFiber; | |
// we wither get an element or false back in this check. | |
const element = index < elements.length && elements[index]; | |
// if the type of the old fiber is the same as the new fiber | |
// we just need to update this fiber | |
// its the same check as the one we had in the previous | |
// reconciliation algorithm | |
const sameType = oldFiber && element && element.type == oldFiber.type; | |
if (sameType) { | |
// on an update the only new thing that gets | |
// changed is the props of the fiber | |
// I should have spread this but for easier | |
// understading and so that we understand where everything | |
// goes and the underlying structure, Ill do what seemengly seems | |
//like im repeating myself. | |
newFiber = { | |
type: oldFiber.type, | |
tag: oldFiber.tag, | |
stateNode: oldFiber.stateNode, | |
props: element.props, | |
parent: wipFiber, | |
alternate: oldFiber, | |
partialState: oldFiber.partialState, | |
effectTag: UPDATE | |
}; | |
} | |
if (element && !sameType) { | |
// this is when an element wasn't present | |
// before but is now present. | |
newFiber = { | |
type: element.type, | |
tag: | |
typeof element.type === "string" ? HOST_COMPONENT : CLASS_COMPONENT, | |
props: element.props, | |
parent: wipFiber, | |
effectTag: PLACEMENT | |
}; | |
} | |
if (oldFiber && !sameType) { | |
// in this check we see its when a component | |
// was present, but is now not present. | |
// like a deleted to do list. | |
oldFiber.effectTag = DELETION; | |
wipFiber.effects = wipFiber.effects || []; | |
// we need to keep a reference of what gets deleted | |
// here we add the fiber to be deleted onto the effects array. | |
// we'll work with the effects later on in the commit stages. | |
wipFiber.effects.push(oldFiber); | |
} | |
if (oldFiber) { | |
// we are only interested in the siblings of the | |
// children that are in the same level here | |
// tree level here | |
// in other terms we just need the siblings of the render array. | |
oldFiber = oldFiber.sibling; | |
} | |
if (index == 0) { | |
wipFiber.child = newFiber; | |
} else if (prevFiber && element) { | |
prevFiber.sibling = newFiber; | |
} | |
index++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment