Compare commits

...

2 Commits

Author SHA1 Message Date
Rick Hanlon
4b9bc21981 Add ReactNativeTypes for root options 2024-04-16 19:59:41 -04:00
Rick Hanlon
425a262527 Add on(Caught|Uncaught|Recoverable) opts to RN 2024-04-13 14:48:55 -07:00
3 changed files with 71 additions and 7 deletions

View File

@@ -10,6 +10,7 @@
import type {ReactPortal, ReactNodeList} from 'shared/ReactTypes';
import type {ElementRef, Element, ElementType} from 'react';
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {RenderRootOptions} from './ReactNativeTypes';
import './ReactFabricInjection';
@@ -106,6 +107,7 @@ function render(
containerTag: number,
callback: ?() => void,
concurrentRoot: ?boolean,
options: ?RenderRootOptions,
): ?ElementRef<ElementType> {
if (disableLegacyMode && !concurrentRoot) {
throw new Error('render: Unsupported Legacy Mode API.');
@@ -114,6 +116,23 @@ function render(
let root = roots.get(containerTag);
if (!root) {
// TODO: these defaults are for backwards compatibility.
// Once RN implements these options internally,
// we can remove the defaults and ReactFiberErrorDialog.
let onUncaughtError = nativeOnUncaughtError;
let onCaughtError = nativeOnCaughtError;
let onRecoverableError = defaultOnRecoverableError;
if (options && options.onUncaughtError !== undefined) {
onUncaughtError = options.onUncaughtError;
}
if (options && options.onCaughtError !== undefined) {
onCaughtError = options.onCaughtError;
}
if (options && options.onRecoverableError !== undefined) {
onRecoverableError = options.onRecoverableError;
}
// TODO (bvaughn): If we decide to keep the wrapper component,
// We could create a wrapper for containerTag as well to reduce special casing.
root = createContainer(
@@ -123,9 +142,9 @@ function render(
false,
null,
'',
nativeOnUncaughtError,
nativeOnCaughtError,
defaultOnRecoverableError,
onUncaughtError,
onCaughtError,
onRecoverableError,
null,
);
roots.set(containerTag, root);

View File

@@ -10,6 +10,7 @@
import type {ReactPortal, ReactNodeList} from 'shared/ReactTypes';
import type {ElementRef, Element, ElementType} from 'react';
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {RenderRootOptions} from './ReactNativeTypes';
import './ReactNativeInjection';
@@ -110,6 +111,7 @@ function render(
element: Element<ElementType>,
containerTag: number,
callback: ?() => void,
options: ?RenderRootOptions,
): ?ElementRef<ElementType> {
if (disableLegacyMode) {
throw new Error('render: Unsupported Legacy Mode API.');
@@ -118,6 +120,23 @@ function render(
let root = roots.get(containerTag);
if (!root) {
// TODO: these defaults are for backwards compatibility.
// Once RN implements these options internally,
// we can remove the defaults and ReactFiberErrorDialog.
let onUncaughtError = nativeOnUncaughtError;
let onCaughtError = nativeOnCaughtError;
let onRecoverableError = defaultOnRecoverableError;
if (options && options.onUncaughtError !== undefined) {
onUncaughtError = options.onUncaughtError;
}
if (options && options.onCaughtError !== undefined) {
onCaughtError = options.onCaughtError;
}
if (options && options.onRecoverableError !== undefined) {
onRecoverableError = options.onRecoverableError;
}
// TODO (bvaughn): If we decide to keep the wrapper component,
// We could create a wrapper for containerTag as well to reduce special casing.
root = createContainer(
@@ -127,9 +146,9 @@ function render(
false,
null,
'',
nativeOnUncaughtError,
nativeOnCaughtError,
defaultOnRecoverableError,
onUncaughtError,
onCaughtError,
onRecoverableError,
null,
);
roots.set(containerTag, root);

View File

@@ -4,8 +4,13 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @noformat
* @flow strict
* @nolint
* @generated SignedSource<<f33ee88cc50bb00a16d281dce9952e21>>
* @generated SignedSource<<dda07b9b2e2bd7345cce0ff966d9fc46>>
*
* This file was sync'd from the facebook/react repository.
*/
import type {ElementRef, ElementType, Element, AbstractComponent} from 'react';
@@ -174,6 +179,25 @@ export type TouchedViewDataAtPoint = $ReadOnly<{
...InspectorData,
}>;
export type RenderRootOptions = {
onUncaughtError?: (
error: mixed,
errorInfo: {+componentStack?: ?string},
) => void,
onCaughtError?: (
error: mixed,
errorInfo: {
+componentStack?: ?string,
// $FlowFixMe[unclear-type] unknown props and state.
+errorBoundary?: ?React$Component<any, any>,
},
) => void,
onRecoverableError?: (
error: mixed,
errorInfo: {+componentStack?: ?string},
) => void,
};
/**
* Flat ReactNative renderer bundles are too big for Flow to parse efficiently.
* Provide minimal Flow typing for the high-level RN API and call it a day.
@@ -202,6 +226,7 @@ export type ReactNativeType = {
element: Element<ElementType>,
containerTag: number,
callback: ?() => void,
options: ?RenderRootOptions,
): ?ElementRef<ElementType>,
unmountComponentAtNode(containerTag: number): void,
unmountComponentAtNodeAndRemoveContainer(containerTag: number): void,
@@ -237,6 +262,7 @@ export type ReactFabricType = {
containerTag: number,
callback: ?() => void,
concurrentRoot: ?boolean,
options: ?RenderRootOptions,
): ?ElementRef<ElementType>,
unmountComponentAtNode(containerTag: number): void,
getNodeFromInternalInstanceHandle(