From 717091ffb8cad80ffcdba9f464f26d18293fec88 Mon Sep 17 00:00:00 2001 From: NE-SmallTown Date: Sat, 20 Jan 2018 22:22:48 +0800 Subject: [PATCH 1/2] add fragment valid --- packages/react/src/React.js | 2 + packages/react/src/ReactElement.js | 12 ++++- packages/react/src/ReactElementValidator.js | 1 - .../react/src/__tests__/ReactElement-test.js | 48 +++++++++++++++++++ .../src/__tests__/ReactJSXElement-test.js | 15 ++++++ 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/react/src/React.js b/packages/react/src/React.js index 61a59f83c530b..9872c13ce2061 100644 --- a/packages/react/src/React.js +++ b/packages/react/src/React.js @@ -17,6 +17,7 @@ import { createFactory, cloneElement, isValidElement, + isValidFragmentElement, } from './ReactElement'; import { createElementWithValidation, @@ -44,6 +45,7 @@ const React = { cloneElement: __DEV__ ? cloneElementWithValidation : cloneElement, createFactory: __DEV__ ? createFactoryWithValidation : createFactory, isValidElement: isValidElement, + isValidFragmentElement: isValidFragmentElement, version: ReactVersion, diff --git a/packages/react/src/ReactElement.js b/packages/react/src/ReactElement.js index a988bfb800033..e42f68e864aed 100644 --- a/packages/react/src/ReactElement.js +++ b/packages/react/src/ReactElement.js @@ -6,7 +6,7 @@ */ import warning from 'fbjs/lib/warning'; -import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols'; +import {REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE} from 'shared/ReactSymbols'; import ReactCurrentOwner from './ReactCurrentOwner'; @@ -368,3 +368,13 @@ export function isValidElement(object) { object.$$typeof === REACT_ELEMENT_TYPE ); } + +/** + * Verifies the object is a ReactFragmentElement. + * @param {?object} object + * @return {boolean} True if `object` is a valid fragment component. + * @final + */ +export function isValidFragmentElement(object) { + return isValidElement(object) && object.type === REACT_FRAGMENT_TYPE; +} diff --git a/packages/react/src/ReactElementValidator.js b/packages/react/src/ReactElementValidator.js index bdf67881a77fb..1ba2c8f50f723 100644 --- a/packages/react/src/ReactElementValidator.js +++ b/packages/react/src/ReactElementValidator.js @@ -273,7 +273,6 @@ function validateFragmentProps(fragment) { getStackAddendum(), ); } - currentlyValidatingElement = null; } diff --git a/packages/react/src/__tests__/ReactElement-test.js b/packages/react/src/__tests__/ReactElement-test.js index 5790767e5b5a3..5f549282e2a44 100644 --- a/packages/react/src/__tests__/ReactElement-test.js +++ b/packages/react/src/__tests__/ReactElement-test.js @@ -314,6 +314,54 @@ describe('ReactElement', () => { expect(React.isValidElement(JSON.parse(jsonElement))).toBe(true); }); + // NOTE: We're explicitly not using JSX here. This is intended to test + // classic JS without JSX. + it('identifies valid fragment elements', () => { + // because we set global.Symbol = undefined in the beforeEach of some tests + // so we can't use `Object.keys` together with `for of` syntax + // in the 'validateFragmentProps' function of ReactElementValidator.js + // it will throw TypeError: can not read property 'interator' of undefined + // so we have to set it to orgin value + global.Symbol = originalSymbol; + + class Component extends React.Component { + render() { + return React.createElement( + React.Fragment, + null, + React.createElement('div'), + ); + } + } + + expect( + React.isValidFragmentElement( + React.createElement(React.Fragment, null, React.createElement('div')), + ), + ).toEqual(true); + + expect( + React.isValidFragmentElement(React.createElement(Component)), + ).toEqual(false); + expect(React.isValidFragmentElement(null)).toEqual(false); + expect(React.isValidFragmentElement(true)).toEqual(false); + expect(React.isValidFragmentElement({})).toEqual(false); + expect(React.isValidFragmentElement('string')).toEqual(false); + expect(React.isValidFragmentElement(React.createFactory('div'))).toEqual( + false, + ); + expect(React.isValidFragmentElement(Component)).toEqual(false); + expect( + React.isValidFragmentElement({type: React.Fragment, props: {}}), + ).toEqual(false); + + // symbol can not be JSON.stringify or JSON.parse, but node has not Symbol now, so + // it be converted to a number, and number can be JSON.stringify + const jsonElement = JSON.stringify(React.createElement(React.Fragment)); + expect(jsonElement).not.toHaveProperty('type'); + expect(React.isValidFragmentElement(JSON.parse(jsonElement))).toBe(true); + }); + // NOTE: We're explicitly not using JSX here. This is intended to test // classic JS without JSX. it('is indistinguishable from a plain object', () => { diff --git a/packages/react/src/__tests__/ReactJSXElement-test.js b/packages/react/src/__tests__/ReactJSXElement-test.js index 920167125f8c4..1be6db355bca2 100644 --- a/packages/react/src/__tests__/ReactJSXElement-test.js +++ b/packages/react/src/__tests__/ReactJSXElement-test.js @@ -165,6 +165,21 @@ describe('ReactJSXElement', () => { expect(React.isValidElement({type: 'div', props: {}})).toEqual(false); }); + it('identifies valid fragment elements', () => { + expect(React.isValidFragmentElement()).toEqual(true); + + expect(React.isValidFragmentElement(
)).toEqual(false); + expect(React.isValidFragmentElement()).toEqual(false); + expect(React.isValidFragmentElement(null)).toEqual(false); + expect(React.isValidFragmentElement(true)).toEqual(false); + expect(React.isValidFragmentElement({})).toEqual(false); + expect(React.isValidFragmentElement('string')).toEqual(false); + expect(React.isValidFragmentElement(Component)).toEqual(false); + expect(React.isValidFragmentElement({type: 'div', props: {}})).toEqual( + false, + ); + }); + it('is indistinguishable from a plain object', () => { const element =
; const object = {}; From 344a0dcbf2f900888b5c60f0b9940bf454f98e6a Mon Sep 17 00:00:00 2001 From: NE-SmallTown Date: Tue, 23 Jan 2018 23:34:41 +0800 Subject: [PATCH 2/2] remove comments --- packages/react/src/__tests__/ReactElement-test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react/src/__tests__/ReactElement-test.js b/packages/react/src/__tests__/ReactElement-test.js index 5f549282e2a44..8a114722a823d 100644 --- a/packages/react/src/__tests__/ReactElement-test.js +++ b/packages/react/src/__tests__/ReactElement-test.js @@ -355,8 +355,6 @@ describe('ReactElement', () => { React.isValidFragmentElement({type: React.Fragment, props: {}}), ).toEqual(false); - // symbol can not be JSON.stringify or JSON.parse, but node has not Symbol now, so - // it be converted to a number, and number can be JSON.stringify const jsonElement = JSON.stringify(React.createElement(React.Fragment)); expect(jsonElement).not.toHaveProperty('type'); expect(React.isValidFragmentElement(JSON.parse(jsonElement))).toBe(true);