Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/isomorphic/classic/element/ReactCurrentOwner.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

'use strict';

import type {ReactInstance} from 'ReactInstanceType';
import type {Fiber} from 'ReactFiber';

/**
Expand All @@ -24,7 +23,7 @@ var ReactCurrentOwner = {
* @internal
* @type {ReactComponent}
*/
current: (null: null | ReactInstance | Fiber),
current: (null: null | Fiber),
};

module.exports = ReactCurrentOwner;
59 changes: 48 additions & 11 deletions src/renderers/dom/fiber/ReactDOMFiberEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

'use strict';

import type {Fiber} from 'ReactFiber';
import type {ReactNodeList} from 'ReactTypes';

require('checkReact');
Expand All @@ -28,6 +27,7 @@ var ReactInputSelection = require('ReactInputSelection');
var ReactInstanceMap = require('ReactInstanceMap');
var ReactPortal = require('ReactPortal');
var ReactVersion = require('ReactVersion');
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
var {injectInternals} = require('ReactFiberDevToolsHook');
var {
ELEMENT_NODE,
Expand All @@ -38,7 +38,7 @@ var {
} = require('HTMLNodeType');
var {ROOT_ATTRIBUTE_NAME} = require('DOMProperty');

var findDOMNode = require('findDOMNode');
var getComponentName = require('getComponentName');
var invariant = require('fbjs/lib/invariant');

var {getChildNamespace} = DOMNamespaces;
Expand Down Expand Up @@ -85,9 +85,6 @@ require('ReactDOMInjection');
ReactControlledComponent.injection.injectFiberControlledHostComponent(
ReactDOMFiberComponent,
);
findDOMNode._injectFiber(function(fiber: Fiber) {
return DOMRenderer.findHostInstance(fiber);
});

type DOMContainer =
| (Element & {
Expand Down Expand Up @@ -232,7 +229,7 @@ var DOMRenderer = ReactFiberReconciler({
if (__DEV__) {
// TODO: take namespace into account when validating.
const hostContextDev = ((hostContext: any): HostContextDev);
validateDOMNesting(type, null, null, hostContextDev.ancestorInfo);
validateDOMNesting(type, null, hostContextDev.ancestorInfo);
if (
typeof props.children === 'string' ||
typeof props.children === 'number'
Expand All @@ -243,7 +240,7 @@ var DOMRenderer = ReactFiberReconciler({
type,
null,
);
validateDOMNesting(null, string, null, ownAncestorInfo);
validateDOMNesting(null, string, ownAncestorInfo);
}
parentNamespace = hostContextDev.namespace;
} else {
Expand Down Expand Up @@ -298,7 +295,7 @@ var DOMRenderer = ReactFiberReconciler({
type,
null,
);
validateDOMNesting(null, string, null, ownAncestorInfo);
validateDOMNesting(null, string, ownAncestorInfo);
}
}
return diffProperties(
Expand Down Expand Up @@ -365,7 +362,7 @@ var DOMRenderer = ReactFiberReconciler({
): TextInstance {
if (__DEV__) {
const hostContextDev = ((hostContext: any): HostContextDev);
validateDOMNesting(null, text, null, hostContextDev.ancestorInfo);
validateDOMNesting(null, text, hostContextDev.ancestorInfo);
}
var textNode: TextInstance = createTextNode(text, rootContainerInstance);
precacheFiberNode(internalInstanceHandle, textNode);
Expand Down Expand Up @@ -675,6 +672,48 @@ function createPortal(
var ReactDOMFiber = {
createPortal,

findDOMNode(
componentOrElement: Element | ?React$Component<any, any>,
): null | Element | Text {
if (__DEV__) {
var owner = (ReactCurrentOwner.current: any);
if (owner !== null) {
var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
warning(
warnedAboutRefsInRender,
'%s is accessing findDOMNode inside its render(). ' +
'render() should be a pure function of props and state. It should ' +
'never access something that requires stale data from the previous ' +
'render, such as refs. Move this logic to componentDidMount and ' +
'componentDidUpdate instead.',
getComponentName(owner) || 'A component',
);
owner.stateNode._warnedAboutRefsInRender = true;
}
}
if (componentOrElement == null) {
return null;
}
if ((componentOrElement: any).nodeType === ELEMENT_NODE) {
return (componentOrElement: any);
}

var inst = ReactInstanceMap.get(componentOrElement);
if (inst) {
return DOMRenderer.findHostInstance(inst);
}

if (typeof componentOrElement.render === 'function') {
invariant(false, 'Unable to find node on an unmounted component.');
} else {
invariant(
false,
'Element appears to be neither ReactComponent nor DOMNode. Keys: %s',
Object.keys(componentOrElement),
);
}
},

hydrate(element: React$Node, container: DOMContainer, callback: ?Function) {
// TODO: throw or warn if we couldn't hydrate?
return renderSubtreeIntoContainer(null, element, container, true, callback);
Expand Down Expand Up @@ -768,8 +807,6 @@ var ReactDOMFiber = {
}
},

findDOMNode: findDOMNode,

// Temporary alias since we already shipped React 16 RC with it.
// TODO: remove in React 17.
unstable_createPortal: createPortal,
Expand Down
16 changes: 0 additions & 16 deletions src/renderers/dom/shared/ReactDOMComponentFlags.js

This file was deleted.

141 changes: 2 additions & 139 deletions src/renderers/dom/shared/ReactDOMComponentTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,116 +9,18 @@

'use strict';

var DOMProperty = require('DOMProperty');
var ReactDOMComponentFlags = require('ReactDOMComponentFlags');
var {HostComponent, HostText} = require('ReactTypeOfWork');
var {ELEMENT_NODE, COMMENT_NODE} = require('HTMLNodeType');

var invariant = require('fbjs/lib/invariant');

var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
var Flags = ReactDOMComponentFlags;

var randomKey = Math.random().toString(36).slice(2);

var internalInstanceKey = '__reactInternalInstance$' + randomKey;

var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;

/**
* Check if a given node should be cached.
*/
function shouldPrecacheNode(node, nodeID) {
return (
(node.nodeType === ELEMENT_NODE &&
node.getAttribute(ATTR_NAME) === '' + nodeID) ||
(node.nodeType === COMMENT_NODE &&
node.nodeValue === ' react-text: ' + nodeID + ' ') ||
(node.nodeType === COMMENT_NODE &&
node.nodeValue === ' react-empty: ' + nodeID + ' ')
);
}

/**
* Drill down (through composites and empty components) until we get a host or
* host text component.
*
* This is pretty polymorphic but unavoidable with the current structure we have
* for `_renderedChildren`.
*/
function getRenderedHostOrTextFromComponent(component) {
var rendered;
while ((rendered = component._renderedComponent)) {
component = rendered;
}
return component;
}

/**
* Populate `_hostNode` on the rendered host/text component with the given
* DOM node. The passed `inst` can be a composite.
*/
function precacheNode(inst, node) {
var hostInst = getRenderedHostOrTextFromComponent(inst);
hostInst._hostNode = node;
node[internalInstanceKey] = hostInst;
}

function precacheFiberNode(hostInst, node) {
node[internalInstanceKey] = hostInst;
}

function uncacheNode(inst) {
var node = inst._hostNode;
if (node) {
delete node[internalInstanceKey];
inst._hostNode = null;
}
}

/**
* Populate `_hostNode` on each child of `inst`, assuming that the children
* match up with the DOM (element) children of `node`.
*
* We cache entire levels at once to avoid an n^2 problem where we access the
* children of a node sequentially and have to walk from the start to our target
* node every time.
*
* Since we update `_renderedChildren` and the actual DOM at (slightly)
* different times, we could race here and see a newer `_renderedChildren` than
* the DOM nodes we see. To avoid this, ReactMultiChild calls
* `prepareToManageChildren` before we change `_renderedChildren`, at which
* time the container's child nodes are always cached (until it unmounts).
*/
function precacheChildNodes(inst, node) {
if (inst._flags & Flags.hasCachedChildNodes) {
return;
}
var children = inst._renderedChildren;
var childNode = node.firstChild;
outer: for (var name in children) {
if (!children.hasOwnProperty(name)) {
continue;
}
var childInst = children[name];
var childID = getRenderedHostOrTextFromComponent(childInst)._domID;
if (childID === 0) {
// We're currently unmounting this child in ReactMultiChild; skip it.
continue;
}
// We assume the child nodes are in the same order as the child instances.
for (; childNode !== null; childNode = childNode.nextSibling) {
if (shouldPrecacheNode(childNode, childID)) {
precacheNode(childInst, childNode);
continue outer;
}
}
// We reached the end of the DOM children without finding an ID match.
invariant(false, 'Unable to find element with ID %s.', childID);
}
inst._flags |= Flags.hasCachedChildNodes;
}

/**
* Given a DOM node, return the closest ReactDOMComponent or
* ReactDOMTextComponent instance ancestor.
Expand Down Expand Up @@ -149,9 +51,6 @@ function getClosestInstanceFromNode(node) {
}
for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) {
closest = inst;
if (parents.length) {
precacheChildNodes(inst, node);
}
}

return closest;
Expand All @@ -166,18 +65,11 @@ function getInstanceFromNode(node) {
if (inst) {
if (inst.tag === HostComponent || inst.tag === HostText) {
return inst;
} else if (inst._hostNode === node) {
return inst;
} else {
return null;
}
}
inst = getClosestInstanceFromNode(node);
if (inst != null && inst._hostNode === node) {
return inst;
} else {
return null;
}
return null;
}

/**
Expand All @@ -193,33 +85,7 @@ function getNodeFromInstance(inst) {

// Without this first invariant, passing a non-DOM-component triggers the next
// invariant for a missing parent, which is super confusing.
invariant(
inst._hostNode !== undefined,
'getNodeFromInstance: Invalid argument.',
);

if (inst._hostNode) {
return inst._hostNode;
}

// Walk up the tree until we find an ancestor whose DOM node we have cached.
var parents = [];
while (!inst._hostNode) {
parents.push(inst);
invariant(
inst._hostParent,
'React DOM tree root should always have a node reference.',
);
inst = inst._hostParent;
}

// Now parents contains each ancestor that does *not* have a cached native
// node, and `inst` is the deepest ancestor that does.
for (; parents.length; inst = parents.pop()) {
precacheChildNodes(inst, inst._hostNode);
}

return inst._hostNode;
invariant(false, 'getNodeFromInstance: Invalid argument.');
}

function getFiberCurrentPropsFromNode(node) {
Expand All @@ -234,9 +100,6 @@ var ReactDOMComponentTree = {
getClosestInstanceFromNode: getClosestInstanceFromNode,
getInstanceFromNode: getInstanceFromNode,
getNodeFromInstance: getNodeFromInstance,
precacheChildNodes: precacheChildNodes,
precacheNode: precacheNode,
uncacheNode: uncacheNode,
precacheFiberNode: precacheFiberNode,
getFiberCurrentPropsFromNode,
updateFiberProps,
Expand Down
22 changes: 7 additions & 15 deletions src/renderers/dom/shared/ReactDOMEventListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,14 @@ function findRootContainerNode(inst) {
// TODO: It may be a good idea to cache this to prevent unnecessary DOM
// traversal, but caching is difficult to do correctly without using a
// mutation observer to listen for all DOM changes.
if (typeof inst.tag === 'number') {
while (inst.return) {
inst = inst.return;
}
if (inst.tag !== HostRoot) {
// This can happen if we're in a detached tree.
return null;
}
return inst.stateNode.containerInfo;
} else {
while (inst._hostParent) {
inst = inst._hostParent;
}
var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst);
return rootNode.parentNode;
while (inst.return) {
inst = inst.return;
}
if (inst.tag !== HostRoot) {
// This can happen if we're in a detached tree.
return null;
}
return inst.stateNode.containerInfo;
}

// Used to store ancestor hierarchy in top level callback
Expand Down
1 change: 0 additions & 1 deletion src/renderers/dom/shared/ReactDOMFeatureFlags.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

var ReactDOMFeatureFlags = {
fiberAsyncScheduling: false,
useFiber: true,
};

module.exports = ReactDOMFeatureFlags;
Loading