|
| 1 | +/** |
| 2 | + * @type |
| 3 | + * @member type - The type of the element. Can be a string (for HTML/SVG tags), a function component (a function that returns a React element), or a class component (a class that extends React.Component and has a render() method). |
| 4 | + * @member props - An object containing the properties passed to the element. These are the properties that are specified in JSX |
| 5 | + * @member key - An optional key that can be used to identify an element in a list. This helps React determine which elements have changed when rendering a list. |
| 6 | + * @member ref - An optional ref that can be used to get a reference to the element's underlying DOM node. This is useful for imperatively manipulating the DOM |
| 7 | + * @member _owner - A reference to the component that created this element. This property is used for debugging purposes only and is not meant to be used in production code. |
| 8 | + */ |
| 9 | + |
| 10 | +interface ReactElement { |
| 11 | + type: string | Function; |
| 12 | + props: { |
| 13 | + [key: string]: any; |
| 14 | + children: ReactElement[]; |
| 15 | + }; |
| 16 | + key: string | null; |
| 17 | + ref: any; |
| 18 | + _owner: FiberNode | null; |
| 19 | +} |
| 20 | + |
| 21 | +/** |
| 22 | + * @type |
| 23 | + * @member element - This property holds the current element that the fiber represents in the render tree. |
| 24 | + * @member parent - This property holds a reference to the parent fiber of the current fiber. |
| 25 | + * @member child - This property holds a reference to the first child fiber of the current fiber. |
| 26 | + * @member sibling - This property holds a reference to the next sibling fiber of the current fiber. |
| 27 | + * @member alternate - This property holds a reference to the corresponding fiber in the previous render (i.e. the "old" fiber). |
| 28 | + * @member effectTag - This property is used to describe the type of update that needs to be made to the DOM when the fiber is committed. It can be one of three values: "PLACEMENT" (for new elements), "UPDATE" (for updates to existing elements), or "DELETION" (for elements that need to be removed from the DOM). |
| 29 | + * @member effects - This property is used to keep track of all the fibers that need to be updated, added, or removed from the DOM during the current commit phase. It is an array of fibers that have been marked with an effectTag other than null. |
| 30 | + */ |
| 31 | + |
| 32 | +interface FiberNode { |
| 33 | + element: ReactElement; |
| 34 | + parent: FiberNode | null; |
| 35 | + child: FiberNode | null; |
| 36 | + sibling: FiberNode | null; |
| 37 | + alternate: FiberNode | null; |
| 38 | + effectTag: string | null; |
| 39 | + effects?: FiberNode[]; |
| 40 | +} |
| 41 | + |
| 42 | +/** |
| 43 | + * |
| 44 | + * @param element |
| 45 | + * @param parent |
| 46 | + * @returns |
| 47 | + */ |
| 48 | +const createFiberNode = (element: ReactElement, parent: FiberNode | null): FiberNode => { |
| 49 | + return { |
| 50 | + element, |
| 51 | + parent, |
| 52 | + child: null, |
| 53 | + sibling: null, |
| 54 | + alternate: null, |
| 55 | + effectTag: null, |
| 56 | + }; |
| 57 | +}; |
| 58 | + |
| 59 | +// Fiber Reconciliation |
| 60 | +const reconcile = (parentFiber: FiberNode, children: any[]) => { |
| 61 | + // checks to see if the parent fiber has an alternate fiber and if it does, it sets oldFiber to its child |
| 62 | + // If there is an alternate fiber for the parent fiber, it means that there was a previous version of the fiber tree that was reconciled, and oldFiber is set to its child fiber so that it can compared to the new children in the current version of the tree |
| 63 | + let oldFiber = parentFiber.alternate && parentFiber.alternate.child; |
| 64 | + let newFiber: FiberNode | null = null; |
| 65 | + let index = 0; // used to keep track of the current index in the children array that is being processed |
| 66 | + let prevFiber: FiberNode | null = null; // used to keep track of the last fiber that was process in the loop |
| 67 | + |
| 68 | + while (index < children.length || !oldFiber) { |
| 69 | + const element = children[index]; |
| 70 | + // see if same type |
| 71 | + let sameType = oldFiber && element && element.type === oldFiber.element.type; |
| 72 | + // if same type is founf, create a newFiber |
| 73 | + if (sameType) { |
| 74 | + newFiber = { |
| 75 | + element, |
| 76 | + child: null, |
| 77 | + sibling: null, |
| 78 | + parent: parentFiber, |
| 79 | + alternate: oldFiber, |
| 80 | + effectTag: 'UPDATE', |
| 81 | + }; |
| 82 | + } |
| 83 | + } |
| 84 | +}; |
| 85 | +// Perform updates to DOM |
0 commit comments