Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Support React.memo and timed-out Suspense trees (#1207)
Browse files Browse the repository at this point in the history
* Fixed display name for `MemoComponent` and `SimpleMemoComponent` types.
* Added display name handling for `IncompleteClassComponent` and `IndeterminateComponent` types.
* Remap parent/child pointers to support suspense hidden subtree reparenting.
* Reorganized v16 tag constants for clarity.
  • Loading branch information
bvaughn authored Nov 7, 2018
1 parent e0b854e commit 14fbbc3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 24 deletions.
46 changes: 26 additions & 20 deletions backend/attachRendererFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function getInternalReactConstants(version) {
HostPortal: 4,
HostRoot: 3,
HostText: 6,
IncompleteClassComponent: 17,
IndeterminateComponent: 2,
LazyComponent: 16,
MemoComponent: 14,
Expand All @@ -63,6 +64,7 @@ function getInternalReactConstants(version) {
HostPortal: 6,
HostRoot: 5,
HostText: 8,
IncompleteClassComponent: -1, // Doesn't exist yet
IndeterminateComponent: 4,
LazyComponent: -1, // Doesn't exist yet
MemoComponent: -1, // Doesn't exist yet
Expand All @@ -86,6 +88,7 @@ function getInternalReactConstants(version) {
HostPortal: 4,
HostRoot: 3,
HostText: 6,
IncompleteClassComponent: -1, // Doesn't exist yet
IndeterminateComponent: 0,
LazyComponent: -1, // Doesn't exist yet
MemoComponent: -1, // Doesn't exist yet
Expand All @@ -106,10 +109,10 @@ function getInternalReactConstants(version) {
CONTEXT_PROVIDER_SYMBOL_STRING: 'Symbol(react.provider)',
FORWARD_REF_NUMBER: 0xead0,
FORWARD_REF_SYMBOL_STRING: 'Symbol(react.forward_ref)',
MEMO_NUMBER: 0xead3,
MEMO_SYMBOL_STRING: 'Symbol(react.memo)',
PROFILER_NUMBER: 0xead2,
PROFILER_SYMBOL_STRING: 'Symbol(react.profiler)',
PURE_NUMBER: 0xead3,
PURE_SYMBOL_STRING: 'Symbol(react.pure)',
STRICT_MODE_NUMBER: 0xeacc,
STRICT_MODE_SYMBOL_STRING: 'Symbol(react.strict_mode)',
SUSPENSE_NUMBER: 0xead1,
Expand Down Expand Up @@ -137,12 +140,16 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer):
FunctionalComponent,
ClassComponent,
ContextConsumer,
Fragment,
ForwardRef,
HostRoot,
HostPortal,
HostComponent,
HostText,
Fragment,
ForwardRef,
IncompleteClassComponent,
IndeterminateComponent,
MemoComponent,
SimpleMemoComponent,
} = ReactTypeOfWork;
var {
CONCURRENT_MODE_NUMBER,
Expand All @@ -154,8 +161,6 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer):
CONTEXT_PROVIDER_SYMBOL_STRING,
PROFILER_NUMBER,
PROFILER_SYMBOL_STRING,
PURE_NUMBER,
PURE_SYMBOL_STRING,
STRICT_MODE_NUMBER,
STRICT_MODE_SYMBOL_STRING,
SUSPENSE_NUMBER,
Expand All @@ -166,6 +171,7 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer):
// TODO: we might want to change the data structure
// once we no longer suppport Stack versions of `getData`.
function getDataFiber(fiber: Object): DataType {
var elementType = fiber.elementType;
var type = fiber.type;
var key = fiber.key;
var ref = fiber.ref;
Expand Down Expand Up @@ -193,11 +199,11 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer):
}
}

// TODO: Add support for new tags LazyComponent, MemoComponent, and SimpleMemoComponent

switch (fiber.tag) {
case FunctionalComponent:
case ClassComponent:
case FunctionalComponent:
case IncompleteClassComponent:
case IndeterminateComponent:
nodeType = 'Composite';
name = getDisplayName(resolvedType);
publicInstance = fiber.stateNode;
Expand Down Expand Up @@ -279,6 +285,17 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer):
nodeType = 'Wrapper';
children = [];
break;
case MemoComponent:
case SimpleMemoComponent:
nodeType = 'Special';
if (elementType.displayName) {
name = elementType.displayName;
} else {
const displayName = type.displayName || type.name;
name = displayName ? `Memo(${displayName})` : 'Memo';
}
children = [];
break;
default:
const symbolOrNumber = typeof type === 'object' && type !== null
? type.$$typeof
Expand All @@ -289,17 +306,6 @@ function attachRendererFiber(hook: Hook, rid: string, renderer: ReactRenderer):
: symbolOrNumber;

switch (switchValue) {
case PURE_NUMBER:
case PURE_SYMBOL_STRING:
nodeType = 'Special';
if (type.displayName) {
name = type.displayName;
} else {
const displayName = type.render.displayName || type.render.name;
name = displayName ? `Pure(${displayName})` : 'Pure';
}
children = [];
break;
case CONCURRENT_MODE_NUMBER:
case CONCURRENT_MODE_SYMBOL_STRING:
case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
Expand Down
19 changes: 15 additions & 4 deletions frontend/Store.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,12 @@ class Store extends EventEmitter {
}

_mountComponent(data: DataType) {
if (this._nodes.has(data.id)) {
// This node has been re-parented.
this._updateComponent(data);
return;
}

var map = Map(data).set('renders', 1);
if (data.nodeType === 'Composite') {
map = map.set('collapsed', true);
Expand All @@ -663,16 +669,18 @@ class Store extends EventEmitter {
}

_updateComponent(data: DataType) {
var node = this.get(data.id);
var id = data.id;
var node = this.get(id);
if (!node) {
return;
}
data.renders = node.get('renders') + 1;
this._nodes = this._nodes.mergeIn([data.id], Map(data));
this._nodes = this._nodes.mergeIn([id], Map(data));
if (data.children && data.children.forEach) {
data.children.forEach(cid => {
if (!this._parents.get(cid)) {
this._parents = this._parents.set(cid, data.id);
var pid = this._parents.get(cid);
if (!pid) {
this._parents = this._parents.set(cid, id);
var childNode = this._nodes.get(cid);
var childID = childNode.get('id');
if (
Expand All @@ -687,6 +695,9 @@ class Store extends EventEmitter {
this.emit('searchRoots');
this.highlightSearch();
}
} else if (pid !== id) {
// This node has been re-parented.
this._parents = this._parents.set(cid, id);
}
});
}
Expand Down

0 comments on commit 14fbbc3

Please sign in to comment.