@samitouri / QOS-React / commits / a432afa750

Ignore specifically React warning getter in ReactElement

We don’t want to have different behavior in development and production. Previously, we used to ignore getters on key/ref in dev, but we’d read them in prod. Now, we only ignore the getters that we *know* we created so the production logic doesn’t differ.

Dan Abramov committed May 26, 2016 at 01:01 UTC a432afa750f0b59412c79c0ca9db4df42a0f8491
3 files changed +55 -83
src/isomorphic/classic/element/ReactElement.js
+45 -36
@@ -34,9 +34,11 @@ var specialPropKeyWarningShown, specialPropRefWarningShown;
34
35 function hasValidRef(config) {
36 if (__DEV__) {
37 - if (hasOwnProperty.call(config, 'ref') &&
38 - Object.getOwnPropertyDescriptor(config, 'ref').get) {
39 - return false;
37 + if (hasOwnProperty.call(config, 'ref')) {
38 + var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
39 + if (getter && getter.isReactWarning) {
40 + return false;
41 + }
42 }
43 }
44 return config.ref !== undefined;
@@ -44,9 +46,11 @@ function hasValidRef(config) {
46
47 function hasValidKey(config) {
48 if (__DEV__) {
47 - if (hasOwnProperty.call(config, 'key') &&
48 - Object.getOwnPropertyDescriptor(config, 'key').get) {
49 - return false;
49 + if (hasOwnProperty.call(config, 'key')) {
50 + var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
51 + if (getter && getter.isReactWarning) {
52 + return false;
53 + }
54 }
55 }
56 return config.key !== undefined;
@@ -201,45 +205,50 @@ ReactElement.createElement = function(type, config, children) {
205 }
206 }
207 if (__DEV__) {
204 - // Create dummy `key` and `ref` property to `props` to warn users
205 - // against its use
208 + // Create dummy `key` and `ref` property to `props` to warn users against its use
209 + function warnAboutAccessingKey() {
210 + if (!specialPropKeyWarningShown) {
211 + specialPropKeyWarningShown = true;
212 + warning(
213 + false,
214 + '%s: `key` is not a prop. Trying to access it will result ' +
215 + 'in `undefined` being returned. If you need to access the same ' +
216 + 'value within the child component, you should pass it as a different ' +
217 + 'prop. (https://fb.me/react-special-props)',
218 + typeof type === 'function' && 'displayName' in type ? type.displayName : 'Element'
219 + );
220 + }
221 + return undefined;
222 + }
223 + warnAboutAccessingKey.isReactWarning = true;
224 +
225 + function warnAboutAccessingRef() {
226 + if (!specialPropRefWarningShown) {
227 + specialPropRefWarningShown = true;
228 + warning(
229 + false,
230 + '%s: `ref` is not a prop. Trying to access it will result ' +
231 + 'in `undefined` being returned. If you need to access the same ' +
232 + 'value within the child component, you should pass it as a different ' +
233 + 'prop. (https://fb.me/react-special-props)',
234 + typeof type === 'function' && 'displayName' in type ? type.displayName : 'Element'
235 + );
236 + }
237 + return undefined;
238 + }
239 + warnAboutAccessingRef.isReactWarning = true;
240 +
241 if (typeof props.$$typeof === 'undefined' ||
242 props.$$typeof !== REACT_ELEMENT_TYPE) {
243 if (!props.hasOwnProperty('key')) {
244 Object.defineProperty(props, 'key', {
210 - get: function() {
211 - if (!specialPropKeyWarningShown) {
212 - specialPropKeyWarningShown = true;
213 - warning(
214 - false,
215 - '%s: `key` is not a prop. Trying to access it will result ' +
216 - 'in `undefined` being returned. If you need to access the same ' +
217 - 'value within the child component, you should pass it as a different ' +
218 - 'prop. (https://fb.me/react-special-props)',
219 - typeof type === 'function' && 'displayName' in type ? type.displayName : 'Element'
220 - );
221 - }
222 - return undefined;
223 - },
245 + get: warnAboutAccessingKey,
246 configurable: true,
247 });
248 }
249 if (!props.hasOwnProperty('ref')) {
250 Object.defineProperty(props, 'ref', {
229 - get: function() {
230 - if (!specialPropRefWarningShown) {
231 - specialPropRefWarningShown = true;
232 - warning(
233 - false,
234 - '%s: `ref` is not a prop. Trying to access it will result ' +
235 - 'in `undefined` being returned. If you need to access the same ' +
236 - 'value within the child component, you should pass it as a different ' +
237 - 'prop. (https://fb.me/react-special-props)',
238 - typeof type === 'function' && 'displayName' in type ? type.displayName : 'Element'
239 - );
240 - }
241 - return undefined;
242 - },
251 + get: warnAboutAccessingRef,
252 configurable: true,
253 });
254 }
src/isomorphic/classic/element/__tests__/ReactElement-test.js
+5 -21
@@ -199,27 +199,11 @@ describe('ReactElement', function() {
199 expect(element.props).toEqual(expectation);
200 });
201
202 - it('ignores key and ref getters', function() {
203 - var props = {
204 - foo: '56',
205 - };
206 - Object.defineProperty(props, 'key', {
207 - get: function() {
208 - return '12';
209 - },
210 - });
211 - Object.defineProperty(props, 'ref', {
212 - get: function() {
213 - return '34';
214 - },
215 - });
216 - var element = React.createFactory(ComponentClass)(props);
217 - expect(element.type).toBe(ComponentClass);
218 - expect(element.key).toBe(null);
219 - expect(element.ref).toBe(null);
220 - var expectation = {foo: '56'};
221 - Object.freeze(expectation);
222 - expect(element.props).toEqual(expectation);
202 + it('ignores key and ref warning getters', function() {
203 + var elementA = React.createElement('div');
204 + var elementB = React.createElement('div', elementA.props);
205 + expect(elementB.key).toBe(null);
206 + expect(elementB.ref).toBe(null);
207 });
208
209 it('coerces the key to a string', function() {
src/isomorphic/classic/element/__tests__/ReactElementClone-test.js
+5 -26
@@ -322,32 +322,11 @@ describe('ReactElementClone', function() {
322 );
323 });
324
325 - it('should ignore key and ref getters', function() {
326 - var element = React.createFactory(ComponentClass)({
327 - key: '12',
328 - ref: '34',
329 - foo: '56',
330 - });
331 - var props = {
332 - foo: 'ef',
333 - };
334 - Object.defineProperty(props, 'key', {
335 - get: function() {
336 - return 'ab';
337 - },
338 - });
339 - Object.defineProperty(props, 'ref', {
340 - get: function() {
341 - return 'cd';
342 - },
343 - });
344 - var clone = React.cloneElement(element, props);
345 - expect(clone.type).toBe(ComponentClass);
346 - expect(clone.key).toBe('12');
347 - expect(clone.ref).toBe('34');
348 - var expectation = {foo: 'ef'};
349 - Object.freeze(expectation);
350 - expect(clone.props).toEqual(expectation);
325 + it('should ignore key and ref warning getters', function() {
326 + var elementA = React.createElement('div');
327 + var elementB = React.cloneElement(elementA, elementA.props);
328 + expect(elementB.key).toBe(null);
329 + expect(elementB.ref).toBe(null);
330 });
331
332 it('should ignore undefined key and ref', function() {