Skip to content

Commit

Permalink
Merge pull request #9 from reactjs/refs
Browse files Browse the repository at this point in the history
Support refs on children
  • Loading branch information
jquense committed Jan 20, 2017
2 parents 06cf519 + 1fdf2d3 commit f00acae
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 11 deletions.
11 changes: 7 additions & 4 deletions package.json
Expand Up @@ -40,7 +40,9 @@
"react-dom": "^15.0.0"
},
"dependencies": {
"dom-helpers": "^3.2.0"
"chain-function": "^1.0.0",
"dom-helpers": "^3.2.0",
"warning": "^3.0.0"
},
"devDependencies": {
"babel-cli": "^6.18.0",
Expand All @@ -58,10 +60,11 @@
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.7.1",
"jest-cli": "^17.0.3",
"react": "^15.4.0",
"react-dom": "^15.4.0",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"release-script": "^1.0.2",
"rimraf": "^2.5.4"
"rimraf": "^2.5.4",
"teaspoon": "^6.4.3"
},
"release-script": {
"altPkgRootFolder": "lib"
Expand Down
15 changes: 12 additions & 3 deletions src/TransitionGroup.js
@@ -1,4 +1,6 @@
import chain from 'chain-function';
import React from 'react';
import warning from 'warning';

import { getChildMapping, mergeChildMappings } from './utils/ChildMapping';

Expand Down Expand Up @@ -187,6 +189,11 @@ class TransitionGroup extends React.Component {
for (let key in this.state.children) {
let child = this.state.children[key];
if (child) {
let isCallbackRef = typeof child.ref !== 'string';
warning(isCallbackRef,
'string refs are not supported on children of TransitionGroup and will be ignored. ' +
'Please use a callback ref instead: https://facebook.github.io/react/docs/refs-and-the-dom.html#the-ref-callback-attribute');

// You may need to apply reactive updates to a child as it is leaving.
// The normal React way to do it won't work since the child will have
// already been removed. In case you need this behavior you can provide
Expand All @@ -196,9 +203,11 @@ class TransitionGroup extends React.Component {
this.props.childFactory(child),
{
key,
ref: (r) => {
this.childRefs[key] = r;
},
ref: chain(
isCallbackRef ? child.ref : null,
(r) => {
this.childRefs[key] = r;
}),
},
));
}
Expand Down
5 changes: 5 additions & 0 deletions test/.eslintrc
Expand Up @@ -5,9 +5,14 @@ env:
rules:
no-require: off
global-require: off
no-console: off
react/no-multi-comp: off
react/no-render-return-value: off
react/no-find-dom-node: off
react/prop-types: off
react/prefer-stateless-function: off
react/jsx-boolean-value: off
react/no-string-refs: off
import/no-extraneous-dependencies:
- error
- devDependencies: true
46 changes: 42 additions & 4 deletions test/TransitionGroup-test.js
@@ -1,3 +1,5 @@
import tsp from 'teaspoon';

let React;
let ReactDOM;
let TransitionGroup;
Expand All @@ -7,10 +9,6 @@ let TransitionGroup;
describe('TransitionGroup', () => {
let container;

// function normalizeCodeLocInfo(str) {
// return str && str.replace(/\(at .+?:\d+\)/g, '(at **)');
// }

beforeEach(() => {
React = require('react');
ReactDOM = require('react-dom');
Expand All @@ -19,6 +17,46 @@ describe('TransitionGroup', () => {
container = document.createElement('div');
});

it('should warn when string refs are used', () => {
class Child extends React.Component {
render() {
return <span />;
}
}

spyOn(console, 'error');

tsp(
<TransitionGroup>
<Child ref="string" />
</TransitionGroup>,
)
.render();

expect(console.error).toHaveBeenCalled();
expect(console.error.calls.mostRecent().args[0]).toMatch(
/string refs are not supported on children of TransitionGroup and will be ignored/,
);
});

it('should allow callback refs', () => {
const ref = jest.fn();

class Child extends React.Component {
render() {
return <span />;
}
}

tsp(
<TransitionGroup>
<Child ref={ref} />
</TransitionGroup>,
)
.render();

expect(ref).toHaveBeenCalled();
});

it('should handle willEnter correctly', () => {
let log = [];
Expand Down

0 comments on commit f00acae

Please sign in to comment.