diff --git a/packages/react-dom/src/client/ReactDOMComponent.js b/packages/react-dom/src/client/ReactDOMComponent.js index 19eb70e583b39..6436cc7977f56 100644 --- a/packages/react-dom/src/client/ReactDOMComponent.js +++ b/packages/react-dom/src/client/ReactDOMComponent.js @@ -317,7 +317,7 @@ function setInitialDOMProperties( if (canSetTextContent) { setTextContent(domElement, nextProp); } - } else if (typeof nextProp === 'number') { + } else if (typeof nextProp === 'number' || typeof nextProp === 'bigint') { setTextContent(domElement, '' + nextProp); } } else if ( diff --git a/packages/react-dom/src/client/ReactDOMHostConfig.js b/packages/react-dom/src/client/ReactDOMHostConfig.js index 3744bbdcdd370..c9d38f7c17c50 100644 --- a/packages/react-dom/src/client/ReactDOMHostConfig.js +++ b/packages/react-dom/src/client/ReactDOMHostConfig.js @@ -254,7 +254,8 @@ export function createInstance( validateDOMNesting(type, null, hostContextDev.ancestorInfo); if ( typeof props.children === 'string' || - typeof props.children === 'number' + typeof props.children === 'number' || + typeof props.children === 'bigint' ) { const string = '' + props.children; const ownAncestorInfo = updatedAncestorInfo( diff --git a/packages/react-dom/src/server/ReactPartialRenderer.js b/packages/react-dom/src/server/ReactPartialRenderer.js index 03f5355ef0e77..60b32fe79533a 100644 --- a/packages/react-dom/src/server/ReactPartialRenderer.js +++ b/packages/react-dom/src/server/ReactPartialRenderer.js @@ -294,7 +294,11 @@ function getNonChildrenInnerMarkup(props) { } } else { const content = props.children; - if (typeof content === 'string' || typeof content === 'number') { + if ( + typeof content === 'string' || + typeof content === 'number' || + typeof content === 'bigint' + ) { return escapeTextForBrowser(content); } } @@ -1001,7 +1005,11 @@ class ReactDOMServerRenderer { context: Object, parentNamespace: string, ): string { - if (typeof child === 'string' || typeof child === 'number') { + if ( + typeof child === 'string' || + typeof child === 'number' || + typeof child === 'bigint' + ) { const text = '' + child; if (text === '') { return ''; diff --git a/packages/react-dom/src/server/escapeTextForBrowser.js b/packages/react-dom/src/server/escapeTextForBrowser.js index 4583cef684902..b2195bb4ae937 100644 --- a/packages/react-dom/src/server/escapeTextForBrowser.js +++ b/packages/react-dom/src/server/escapeTextForBrowser.js @@ -104,7 +104,11 @@ function escapeHtml(string) { * @return {string} An escaped string. */ function escapeTextForBrowser(text) { - if (typeof text === 'boolean' || typeof text === 'number') { + if ( + typeof text === 'boolean' || + typeof text === 'number' || + typeof text === 'bigint' + ) { // this shortcircuit helps perf for types that we know will never have // special characters, especially given that this function is used often // for numeric dom ids. diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index 24970fbcc18d0..8505028f31b8e 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -263,7 +263,9 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { throw new Error('Error in host config.'); } return ( - typeof props.children === 'string' || typeof props.children === 'number' + typeof props.children === 'string' || + typeof props.children === 'number' || + typeof props.children === 'bigint' ); } diff --git a/packages/react-reconciler/src/ReactChildFiber.new.js b/packages/react-reconciler/src/ReactChildFiber.new.js index e7eb67328af09..410c7c4daa711 100644 --- a/packages/react-reconciler/src/ReactChildFiber.new.js +++ b/packages/react-reconciler/src/ReactChildFiber.new.js @@ -490,7 +490,8 @@ function ChildReconciler(shouldTrackSideEffects) { ): Fiber | null { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { // Text nodes don't have keys. If the previous node is implicitly keyed // we can continue to replace it without aborting even if it is not a text @@ -567,7 +568,8 @@ function ChildReconciler(shouldTrackSideEffects) { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { // Text nodes don't have keys. If the previous node is implicitly keyed // we can continue to replace it without aborting even if it is not a text @@ -630,7 +632,8 @@ function ChildReconciler(shouldTrackSideEffects) { ): Fiber | null { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { // Text nodes don't have keys, so we neither have to check the old nor // new node for the key. If both are text nodes, they match. @@ -1321,7 +1324,8 @@ function ChildReconciler(shouldTrackSideEffects) { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { return placeSingleChild( reconcileSingleTextNode( diff --git a/packages/react-reconciler/src/ReactChildFiber.old.js b/packages/react-reconciler/src/ReactChildFiber.old.js index 320924d6030ec..f670d2df99a2e 100644 --- a/packages/react-reconciler/src/ReactChildFiber.old.js +++ b/packages/react-reconciler/src/ReactChildFiber.old.js @@ -490,7 +490,8 @@ function ChildReconciler(shouldTrackSideEffects) { ): Fiber | null { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { // Text nodes don't have keys. If the previous node is implicitly keyed // we can continue to replace it without aborting even if it is not a text @@ -567,7 +568,8 @@ function ChildReconciler(shouldTrackSideEffects) { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { // Text nodes don't have keys. If the previous node is implicitly keyed // we can continue to replace it without aborting even if it is not a text @@ -630,7 +632,8 @@ function ChildReconciler(shouldTrackSideEffects) { ): Fiber | null { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { // Text nodes don't have keys, so we neither have to check the old nor // new node for the key. If both are text nodes, they match. @@ -1321,7 +1324,8 @@ function ChildReconciler(shouldTrackSideEffects) { if ( (typeof newChild === 'string' && newChild !== '') || - typeof newChild === 'number' + typeof newChild === 'number' || + typeof newChild === 'bigint' ) { return placeSingleChild( reconcileSingleTextNode( diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index a8a3fe6932072..4fc69306940e6 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -1352,7 +1352,7 @@ function renderNodeDestructiveImpl( return; } - if (typeof node === 'number') { + if (typeof node === 'number' || typeof node === 'bigint') { const segment = task.blockedSegment; segment.lastPushedText = pushTextInstance( task.blockedSegment.chunks, diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 814f8f1a4f9d2..ca23371f9f114 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -667,6 +667,7 @@ export function resolveModelToJSON( if ( typeof value === 'boolean' || typeof value === 'number' || + typeof value === 'bigint' || typeof value === 'undefined' ) { return value; diff --git a/packages/react/src/ReactChildren.js b/packages/react/src/ReactChildren.js index d0562f53e3bc9..591413c2372b4 100644 --- a/packages/react/src/ReactChildren.js +++ b/packages/react/src/ReactChildren.js @@ -96,6 +96,7 @@ function mapIntoArray( switch (type) { case 'string': case 'number': + case 'bigint': invokeCallback = true; break; case 'object':