Skip to content

Instantly share code, notes, and snippets.

@Tevinthuku
Last active August 14, 2019 17:24
Show Gist options
  • Save Tevinthuku/303aaff6412b31dbdece2202dde0dd7c to your computer and use it in GitHub Desktop.
Save Tevinthuku/303aaff6412b31dbdece2202dde0dd7c to your computer and use it in GitHub Desktop.
reconciling children
// .. 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