From b1aa8166922a095f7878bbf1960e039712b9c6ed Mon Sep 17 00:00:00 2001 From: Jason Quense Date: Fri, 20 Jan 2017 11:17:31 -0500 Subject: [PATCH 1/2] Support refs on children --- package.json | 11 +++++---- src/TransitionGroup.js | 15 +++++++++--- test/.eslintrc | 5 ++++ test/TransitionGroup-test.js | 46 ++++++++++++++++++++++++++++++++---- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index f1cc260a..d6923d64 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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" diff --git a/src/TransitionGroup.js b/src/TransitionGroup.js index b6d49766..0a962487 100644 --- a/src/TransitionGroup.js +++ b/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'; @@ -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 === 'function'; + warning(!child.ref || 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 @@ -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; + }), }, )); } diff --git a/test/.eslintrc b/test/.eslintrc index c07af15d..2cfb7601 100644 --- a/test/.eslintrc +++ b/test/.eslintrc @@ -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 diff --git a/test/TransitionGroup-test.js b/test/TransitionGroup-test.js index 4b537413..86b7d13c 100644 --- a/test/TransitionGroup-test.js +++ b/test/TransitionGroup-test.js @@ -1,3 +1,5 @@ +import tsp from 'teaspoon'; + let React; let ReactDOM; let TransitionGroup; @@ -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'); @@ -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 ; + } + } + + spyOn(console, 'error'); + + tsp( + + + , + ) + .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 ; + } + } + + tsp( + + + , + ) + .render(); + + expect(ref).toHaveBeenCalled(); + }); it('should handle willEnter correctly', () => { let log = []; From 1fdf2d31ac1d6845af7522e4263a899a9344cca3 Mon Sep 17 00:00:00 2001 From: Jason Quense Date: Fri, 20 Jan 2017 15:05:37 -0500 Subject: [PATCH 2/2] simpler check --- src/TransitionGroup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TransitionGroup.js b/src/TransitionGroup.js index 0a962487..775f6268 100644 --- a/src/TransitionGroup.js +++ b/src/TransitionGroup.js @@ -189,8 +189,8 @@ 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 === 'function'; - warning(!child.ref || isCallbackRef, + 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');