Skip to content

Commit fc5582d

Browse files
committed
ReactMount now never expects invalid nodes in its cache
It never really made sense for us to have "invalid" nodes in the cache -- when we unmount things, we should always remove them from the cache properly. Now that swapping composite types doesn't repopulate the cache, we should be okay to now assume that everything in the cache is good.
1 parent e882276 commit fc5582d

File tree

1 file changed

+33
-24
lines changed

1 file changed

+33
-24
lines changed

src/renderers/dom/client/ReactMount.js

+33-24
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function getReactRootElementInContainer(container) {
9999
*/
100100
function getReactRootID(container) {
101101
var rootElement = getReactRootElementInContainer(container);
102-
return rootElement && ReactMount.getID(rootElement);
102+
return rootElement && internalGetID(rootElement);
103103
}
104104

105105
/**
@@ -115,20 +115,12 @@ function getReactRootID(container) {
115115
function getID(node) {
116116
var id = internalGetID(node);
117117
if (id) {
118-
if (nodeCache.hasOwnProperty(id)) {
119-
var cached = nodeCache[id];
120-
if (cached !== node) {
121-
invariant(
122-
!isValid(cached, id),
123-
'ReactMount: Two valid but unequal nodes with the same `%s`: %s',
124-
ATTR_NAME, id
125-
);
126-
127-
nodeCache[id] = node;
128-
}
129-
} else {
130-
nodeCache[id] = node;
131-
}
118+
invariant(
119+
!nodeCache.hasOwnProperty(id) || nodeCache[id] === node,
120+
'ReactMount: Two unequal nodes with the same `%s`: %s',
121+
ATTR_NAME, id
122+
);
123+
nodeCache[id] = node;
132124
}
133125

134126
return id;
@@ -156,6 +148,25 @@ function setID(node, id) {
156148
nodeCache[id] = node;
157149
}
158150

151+
/**
152+
* Finds the node with the supplied ID if present in the cache.
153+
*/
154+
function getNodeIfCached(id) {
155+
var node = nodeCache[id];
156+
// TODO: Since this "isValid" business is now just a sanity check, we can
157+
// probably drop it with no consequences.
158+
invariant(
159+
!node || isValid(node, id),
160+
'ReactMount: Cached node with `%s`: %s is missing from the document. ' +
161+
'This probably means the DOM was unexpectedly mutated -- when removing ' +
162+
'React-rendered children from the DOM, rerender without those children ' +
163+
'or call ReactDOM.unmountComponentAtNode on the container to unmount an ' +
164+
'entire subtree.',
165+
ATTR_NAME, id
166+
);
167+
return node;
168+
}
169+
159170
/**
160171
* Finds the node with the supplied React-generated DOM ID.
161172
*
@@ -164,10 +175,11 @@ function setID(node, id) {
164175
* @internal
165176
*/
166177
function getNode(id) {
167-
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
168-
nodeCache[id] = ReactMount.findReactNodeByID(id);
178+
if (nodeCache.hasOwnProperty(id)) {
179+
return getNodeIfCached(id);
180+
} else {
181+
return nodeCache[id] = ReactMount.findReactNodeByID(id);
169182
}
170-
return nodeCache[id];
171183
}
172184

173185
/**
@@ -182,10 +194,7 @@ function getNodeFromInstance(instance) {
182194
if (ReactEmptyComponentRegistry.isNullComponentID(id)) {
183195
return null;
184196
}
185-
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
186-
nodeCache[id] = ReactMount.findReactNodeByID(id);
187-
}
188-
return nodeCache[id];
197+
return getNode(id);
189198
}
190199

191200
/**
@@ -226,8 +235,8 @@ function purgeID(id) {
226235

227236
var deepestNodeSoFar = null;
228237
function findDeepestCachedAncestorImpl(ancestorID) {
229-
var ancestor = nodeCache[ancestorID];
230-
if (ancestor && isValid(ancestor, ancestorID)) {
238+
var ancestor = getNodeIfCached(ancestorID);
239+
if (ancestor) {
231240
deepestNodeSoFar = ancestor;
232241
} else {
233242
// This node isn't populated in the cache, so presumably none of its

0 commit comments

Comments
 (0)