diff --git a/packages/react-dom/src/__tests__/refs-destruction-test.js b/packages/react-dom/src/__tests__/refs-destruction-test.js
index bbb24c97e7026..6c6158d6b7512 100644
--- a/packages/react-dom/src/__tests__/refs-destruction-test.js
+++ b/packages/react-dom/src/__tests__/refs-destruction-test.js
@@ -23,15 +23,31 @@ describe('refs-destruction', () => {
ReactDOM = require('react-dom');
ReactTestUtils = require('react-dom/test-utils');
+ class ClassComponent extends React.Component {
+ render() {
+ return null;
+ }
+ }
+
TestComponent = class extends React.Component {
render() {
- return (
-
- {this.props.destroy ? null : (
-
Lets try to destroy this.
- )}
-
- );
+ if (this.props.destroy) {
+ return ;
+ } else if (this.props.removeRef) {
+ return (
+
+ );
+ } else {
+ return (
+
+ );
+ }
}
};
});
@@ -45,7 +61,7 @@ describe('refs-destruction', () => {
expect(
Object.keys(testInstance.refs || {}).filter(key => testInstance.refs[key])
.length,
- ).toEqual(1);
+ ).toEqual(2);
ReactDOM.unmountComponentAtNode(container);
expect(
Object.keys(testInstance.refs || {}).filter(key => testInstance.refs[key])
@@ -62,7 +78,7 @@ describe('refs-destruction', () => {
expect(
Object.keys(testInstance.refs || {}).filter(key => testInstance.refs[key])
.length,
- ).toEqual(1);
+ ).toEqual(2);
ReactDOM.render(, container);
expect(
Object.keys(testInstance.refs || {}).filter(key => testInstance.refs[key])
@@ -70,6 +86,23 @@ describe('refs-destruction', () => {
).toEqual(0);
});
+ it('should remove refs when removing the child ref attribute', () => {
+ const container = document.createElement('div');
+ const testInstance = ReactDOM.render(, container);
+ expect(ReactTestUtils.isDOMComponent(testInstance.refs.theInnerDiv)).toBe(
+ true,
+ );
+ expect(
+ Object.keys(testInstance.refs || {}).filter(key => testInstance.refs[key])
+ .length,
+ ).toEqual(2);
+ ReactDOM.render(, container);
+ expect(
+ Object.keys(testInstance.refs || {}).filter(key => testInstance.refs[key])
+ .length,
+ ).toEqual(0);
+ });
+
it('should not error when destroying child with ref asynchronously', () => {
class Modal extends React.Component {
componentDidMount() {
diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js
index 67b22f96cd837..7e2be7b79c54d 100644
--- a/packages/react-reconciler/src/ReactFiberBeginWork.js
+++ b/packages/react-reconciler/src/ReactFiberBeginWork.js
@@ -184,7 +184,10 @@ export default function(
function markRef(current: Fiber | null, workInProgress: Fiber) {
const ref = workInProgress.ref;
- if (ref !== null && (!current || current.ref !== ref)) {
+ if (
+ (current === null && ref !== null) ||
+ (current !== null && current.ref !== ref)
+ ) {
// Schedule a Ref effect
workInProgress.effectTag |= Ref;
}