Skip to content

Commit 6174a22

Browse files
committed
Add incremental reconciliation (Didact Fiber)
1 parent ab2b562 commit 6174a22

10 files changed

+382
-144
lines changed

src/component.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
import { reconcile } from "./reconciler";
1+
import { scheduleUpdate } from "./reconciler";
22

33
export class Component {
44
constructor(props) {
5-
this.props = props;
5+
this.props = props || {};
66
this.state = this.state || {};
77
}
88

99
setState(partialState) {
10-
this.state = Object.assign({}, this.state, partialState);
11-
updateInstance(this.__internalInstance);
10+
scheduleUpdate(this, partialState);
1211
}
1312
}
1413

15-
function updateInstance(internalInstance) {
16-
const parentDom = internalInstance.dom.parentNode;
17-
const element = internalInstance.element;
18-
reconcile(parentDom, internalInstance, element);
19-
}
20-
21-
export function createPublicInstance(element, internalInstance) {
22-
const { type, props } = element;
23-
const publicInstance = new type(props);
24-
publicInstance.__internalInstance = internalInstance;
25-
return publicInstance;
14+
export function createInstance(fiber) {
15+
const instance = new fiber.type(fiber.props);
16+
instance.__fiber = fiber;
17+
return instance;
2618
}

src/dom-utils.js

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,66 @@
1-
export function updateDomProperties(dom, prevProps, nextProps) {
2-
const isEvent = name => name.startsWith("on");
3-
const isAttribute = name => !isEvent(name) && name != "children";
1+
import { TEXT_ELEMENT } from "./element";
2+
3+
const isEvent = name => name.startsWith("on");
4+
const isAttribute = name =>
5+
!isEvent(name) && name != "children" && name != "style";
6+
const isNew = (prev, next) => key => prev[key] !== next[key];
7+
const isGone = (prev, next) => key => !(key in next);
48

9+
export function updateDomProperties(dom, prevProps, nextProps) {
510
// Remove event listeners
6-
Object.keys(prevProps).filter(isEvent).forEach(name => {
7-
const eventType = name.toLowerCase().substring(2);
8-
dom.removeEventListener(eventType, prevProps[name]);
9-
});
11+
Object.keys(prevProps)
12+
.filter(isEvent)
13+
.filter(key => !(key in nextProps) || isNew(prevProps, nextProps)(key))
14+
.forEach(name => {
15+
const eventType = name.toLowerCase().substring(2);
16+
dom.removeEventListener(eventType, prevProps[name]);
17+
});
1018

1119
// Remove attributes
12-
Object.keys(prevProps).filter(isAttribute).forEach(name => {
13-
dom[name] = null;
14-
});
20+
Object.keys(prevProps)
21+
.filter(isAttribute)
22+
.filter(isGone(prevProps, nextProps))
23+
.forEach(name => {
24+
dom[name] = null;
25+
});
1526

1627
// Set attributes
17-
Object.keys(nextProps).filter(isAttribute).forEach(name => {
18-
dom[name] = nextProps[name];
19-
});
28+
Object.keys(nextProps)
29+
.filter(isAttribute)
30+
.filter(isNew(prevProps, nextProps))
31+
.forEach(name => {
32+
dom[name] = nextProps[name];
33+
});
34+
35+
// Set style
36+
prevProps.style = prevProps.style || {};
37+
nextProps.style = nextProps.style || {};
38+
Object.keys(nextProps.style)
39+
.filter(isNew(prevProps.style, nextProps.style))
40+
.forEach(key => {
41+
dom.style[key] = nextProps.style[key];
42+
});
43+
Object.keys(prevProps.style)
44+
.filter(isGone(prevProps.style, nextProps.style))
45+
.forEach(key => {
46+
dom.style[key] = "";
47+
});
2048

2149
// Add event listeners
22-
Object.keys(nextProps).filter(isEvent).forEach(name => {
23-
const eventType = name.toLowerCase().substring(2);
24-
dom.addEventListener(eventType, nextProps[name]);
25-
});
50+
Object.keys(nextProps)
51+
.filter(isEvent)
52+
.filter(isNew(prevProps, nextProps))
53+
.forEach(name => {
54+
const eventType = name.toLowerCase().substring(2);
55+
dom.addEventListener(eventType, nextProps[name]);
56+
});
57+
}
58+
59+
export function createDomElement(fiber) {
60+
const isTextElement = fiber.type === TEXT_ELEMENT;
61+
const dom = isTextElement
62+
? document.createTextNode("")
63+
: document.createElement(fiber.type);
64+
updateDomProperties(dom, [], fiber.props);
65+
return dom;
2666
}

0 commit comments

Comments
 (0)