mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove experimental useOpaqueIdentifier API (#22672)
useId is the updated version of this API.
This commit is contained in:
1 parent
8c4a05b8fb
commit
75f3ddebfa
39 files changed
+22
-1790
No files matched your search
-18
@@ -436,24 +436,6 @@ export function getInstanceFromNode(node) {
|
||||
throw new Error('Not implemented.');
|
||||
}
|
||||
|
||||
export function isOpaqueHydratingObject(value: mixed): boolean {
|
||||
throw new Error('Not implemented.');
|
||||
}
|
||||
|
||||
export function makeOpaqueHydratingObject(
|
||||
attemptToReadValue: () => void,
|
||||
): OpaqueIDType {
|
||||
throw new Error('Not implemented.');
|
||||
}
|
||||
|
||||
export function makeClientId(): OpaqueIDType {
|
||||
throw new Error('Not implemented.');
|
||||
}
|
||||
|
||||
export function makeClientIdInDEV(warnOnAccessInDEV: () => void): OpaqueIDType {
|
||||
throw new Error('Not implemented.');
|
||||
}
|
||||
|
||||
export function beforeActiveInstanceBlur(internalInstanceHandle: Object) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -18,13 +18,9 @@ import type {
|
||||
Fiber,
|
||||
Dispatcher as DispatcherType,
|
||||
} from 'react-reconciler/src/ReactInternalTypes';
|
||||
import type {OpaqueIDType} from 'react-reconciler/src/ReactFiberHostConfig';
|
||||
|
||||
import {NoMode} from 'react-reconciler/src/ReactTypeOfMode';
|
||||
|
||||
import ErrorStackParser from 'error-stack-parser';
|
||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||
import {REACT_OPAQUE_ID_TYPE} from 'shared/ReactSymbols';
|
||||
import {
|
||||
FunctionComponent,
|
||||
SimpleMemoComponent,
|
||||
@@ -53,8 +49,6 @@ type Dispatch<A> = A => void;
|
||||
|
||||
let primitiveStackCache: null | Map<string, Array<any>> = null;
|
||||
|
||||
let currentFiber: Fiber | null = null;
|
||||
|
||||
type Hook = {
|
||||
memoizedState: any,
|
||||
next: Hook | null,
|
||||
@@ -324,23 +318,6 @@ function useDeferredValue<T>(value: T): T {
|
||||
return value;
|
||||
}
|
||||
|
||||
function useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const hook = nextHook(); // State
|
||||
if (currentFiber && currentFiber.mode === NoMode) {
|
||||
nextHook(); // Effect
|
||||
}
|
||||
let value = hook === null ? undefined : hook.memoizedState;
|
||||
if (value && value.$$typeof === REACT_OPAQUE_ID_TYPE) {
|
||||
value = undefined;
|
||||
}
|
||||
hookLog.push({
|
||||
primitive: 'OpaqueIdentifier',
|
||||
stackError: new Error(),
|
||||
value,
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
function useId(): string {
|
||||
const hook = nextHook();
|
||||
const id = hook !== null ? hook.memoizedState : '';
|
||||
@@ -371,7 +348,6 @@ const Dispatcher: DispatcherType = {
|
||||
useMutableSource,
|
||||
useSyncExternalStore,
|
||||
useDeferredValue,
|
||||
useOpaqueIdentifier,
|
||||
useId,
|
||||
};
|
||||
|
||||
@@ -767,8 +743,6 @@ export function inspectHooksOfFiber(
|
||||
currentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
|
||||
}
|
||||
|
||||
currentFiber = fiber;
|
||||
|
||||
if (
|
||||
fiber.tag !== FunctionComponent &&
|
||||
fiber.tag !== SimpleMemoComponent &&
|
||||
|
||||
-58
@@ -598,64 +598,6 @@ describe('ReactHooksInspectionIntegration', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should support composite useOpaqueIdentifier hook', () => {
|
||||
function Foo(props) {
|
||||
const id = React.unstable_useOpaqueIdentifier();
|
||||
const [state] = React.useState(() => 'hello', []);
|
||||
return <div id={id}>{state}</div>;
|
||||
}
|
||||
|
||||
const renderer = ReactTestRenderer.create(<Foo />);
|
||||
const childFiber = renderer.root.findByType(Foo)._currentFiber();
|
||||
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
|
||||
|
||||
expect(tree.length).toEqual(2);
|
||||
|
||||
expect(tree[0].id).toEqual(0);
|
||||
expect(tree[0].isStateEditable).toEqual(false);
|
||||
expect(tree[0].name).toEqual('OpaqueIdentifier');
|
||||
expect(String(tree[0].value).startsWith('c_')).toBe(true);
|
||||
|
||||
expect(tree[1]).toEqual({
|
||||
id: 1,
|
||||
isStateEditable: true,
|
||||
name: 'State',
|
||||
value: 'hello',
|
||||
subHooks: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should support composite useOpaqueIdentifier hook in concurrent mode', () => {
|
||||
function Foo(props) {
|
||||
const id = React.unstable_useOpaqueIdentifier();
|
||||
const [state] = React.useState('hello');
|
||||
return <div id={id}>{state}</div>;
|
||||
}
|
||||
|
||||
const renderer = ReactTestRenderer.create(<Foo />, {
|
||||
unstable_isConcurrent: true,
|
||||
});
|
||||
expect(Scheduler).toFlushWithoutYielding();
|
||||
|
||||
const childFiber = renderer.root.findByType(Foo)._currentFiber();
|
||||
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
|
||||
|
||||
expect(tree.length).toEqual(2);
|
||||
|
||||
expect(tree[0].id).toEqual(0);
|
||||
expect(tree[0].isStateEditable).toEqual(false);
|
||||
expect(tree[0].name).toEqual('OpaqueIdentifier');
|
||||
expect(String(tree[0].value).startsWith('c_')).toBe(true);
|
||||
|
||||
expect(tree[1]).toEqual({
|
||||
id: 1,
|
||||
isStateEditable: true,
|
||||
name: 'State',
|
||||
value: 'hello',
|
||||
subHooks: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should support useId hook', () => {
|
||||
function Foo(props) {
|
||||
const id = React.unstable_useId();
|
||||
|
||||
@@ -40,9 +40,6 @@ export const LAZY_SYMBOL_STRING = 'Symbol(react.lazy)';
|
||||
export const MEMO_NUMBER = 0xead3;
|
||||
export const MEMO_SYMBOL_STRING = 'Symbol(react.memo)';
|
||||
|
||||
export const OPAQUE_ID_NUMBER = 0xeae0;
|
||||
export const OPAQUE_ID_SYMBOL_STRING = 'Symbol(react.opaque.id)';
|
||||
|
||||
export const PORTAL_NUMBER = 0xeaca;
|
||||
export const PORTAL_SYMBOL_STRING = 'Symbol(react.portal)';
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -21,7 +21,6 @@ import {
|
||||
enableTrustedTypesIntegration,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {checkAttributeStringCoercion} from 'shared/CheckStringCoercion';
|
||||
import {isOpaqueHydratingObject} from './ReactDOMHostConfig';
|
||||
|
||||
import type {PropertyInfo} from '../shared/DOMProperty';
|
||||
|
||||
@@ -119,13 +118,6 @@ export function getValueForAttribute(
|
||||
if (!isAttributeNameSafe(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the object is an opaque reference ID, it's expected that
|
||||
// the next prop is different than the server value, so just return
|
||||
// expected
|
||||
if (isOpaqueHydratingObject(expected)) {
|
||||
return expected;
|
||||
}
|
||||
if (!node.hasAttribute(name)) {
|
||||
return expected === undefined ? undefined : null;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ import possibleStandardNames from '../shared/possibleStandardNames';
|
||||
import {validateProperties as validateARIAProperties} from '../shared/ReactDOMInvalidARIAHook';
|
||||
import {validateProperties as validateInputProperties} from '../shared/ReactDOMNullInputValuePropHook';
|
||||
import {validateProperties as validateUnknownProperties} from '../shared/ReactDOMUnknownPropertyHook';
|
||||
import {REACT_OPAQUE_ID_TYPE} from 'shared/ReactSymbols';
|
||||
|
||||
import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags';
|
||||
import {
|
||||
@@ -775,15 +774,6 @@ export function diffProperties(
|
||||
// to update this element.
|
||||
updatePayload = [];
|
||||
}
|
||||
} else if (
|
||||
typeof nextProp === 'object' &&
|
||||
nextProp !== null &&
|
||||
nextProp.$$typeof === REACT_OPAQUE_ID_TYPE
|
||||
) {
|
||||
// If we encounter useOpaqueReference's opaque object, this means we are hydrating.
|
||||
// In this case, call the opaque object's toString function which generates a new client
|
||||
// ID so client and server IDs match and throws to rerender.
|
||||
nextProp.toString();
|
||||
} else {
|
||||
// For any other property we always add it to the queue and then we
|
||||
// filter it out using the allowed property list during the commit.
|
||||
|
||||
@@ -59,7 +59,6 @@ import {
|
||||
} from '../shared/HTMLNodeType';
|
||||
import dangerousStyleValue from '../shared/dangerousStyleValue';
|
||||
|
||||
import {REACT_OPAQUE_ID_TYPE} from 'shared/ReactSymbols';
|
||||
import {retryIfBlockedOn} from '../events/ReactDOMEventReplaying';
|
||||
|
||||
import {
|
||||
@@ -124,13 +123,6 @@ export type TimeoutHandle = TimeoutID;
|
||||
export type NoTimeout = -1;
|
||||
export type RendererInspectionConfig = $ReadOnly<{||}>;
|
||||
|
||||
export opaque type OpaqueIDType =
|
||||
| string
|
||||
| {
|
||||
toString: () => string | void,
|
||||
valueOf: () => string | void,
|
||||
};
|
||||
|
||||
type SelectionInformation = {|
|
||||
focusedElem: null | HTMLElement,
|
||||
selectionRange: mixed,
|
||||
@@ -1089,43 +1081,6 @@ export function getInstanceFromNode(node: HTMLElement): null | Object {
|
||||
return getClosestInstanceFromNode(node) || null;
|
||||
}
|
||||
|
||||
let clientId: number = 0;
|
||||
export function makeClientId(): OpaqueIDType {
|
||||
return 'r:' + (clientId++).toString(36);
|
||||
}
|
||||
|
||||
export function makeClientIdInDEV(warnOnAccessInDEV: () => void): OpaqueIDType {
|
||||
const id = 'r:' + (clientId++).toString(36);
|
||||
return {
|
||||
toString() {
|
||||
warnOnAccessInDEV();
|
||||
return id;
|
||||
},
|
||||
valueOf() {
|
||||
warnOnAccessInDEV();
|
||||
return id;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function isOpaqueHydratingObject(value: mixed): boolean {
|
||||
return (
|
||||
value !== null &&
|
||||
typeof value === 'object' &&
|
||||
value.$$typeof === REACT_OPAQUE_ID_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
export function makeOpaqueHydratingObject(
|
||||
attemptToReadValue: () => void,
|
||||
): OpaqueIDType {
|
||||
return {
|
||||
$$typeof: REACT_OPAQUE_ID_TYPE,
|
||||
toString: attemptToReadValue,
|
||||
valueOf: attemptToReadValue,
|
||||
};
|
||||
}
|
||||
|
||||
export function preparePortalMount(portalInstance: Instance): void {
|
||||
listenToAllSupportedEvents(portalInstance);
|
||||
}
|
||||
|
||||
@@ -64,9 +64,7 @@ export type ResponseState = {
|
||||
placeholderPrefix: PrecomputedChunk,
|
||||
segmentPrefix: PrecomputedChunk,
|
||||
boundaryPrefix: string,
|
||||
opaqueIdentifierPrefix: string,
|
||||
nextSuspenseID: number,
|
||||
nextOpaqueID: number,
|
||||
sentCompleteSegmentFunction: boolean,
|
||||
sentCompleteBoundaryFunction: boolean,
|
||||
sentClientRenderFunction: boolean, // We allow the legacy renderer to extend this object.
|
||||
@@ -127,9 +125,7 @@ export function createResponseState(
|
||||
placeholderPrefix: stringToPrecomputedChunk(idPrefix + 'P:'),
|
||||
segmentPrefix: stringToPrecomputedChunk(idPrefix + 'S:'),
|
||||
boundaryPrefix: idPrefix + 'B:',
|
||||
opaqueIdentifierPrefix: idPrefix + 'R:',
|
||||
nextSuspenseID: 0,
|
||||
nextOpaqueID: 0,
|
||||
sentCompleteSegmentFunction: false,
|
||||
sentCompleteBoundaryFunction: false,
|
||||
sentClientRenderFunction: false,
|
||||
@@ -233,24 +229,6 @@ export function assignSuspenseBoundaryID(
|
||||
);
|
||||
}
|
||||
|
||||
export type OpaqueIDType = string;
|
||||
|
||||
export function makeServerID(
|
||||
responseState: null | ResponseState,
|
||||
): OpaqueIDType {
|
||||
if (responseState === null) {
|
||||
throw new Error(
|
||||
'Invalid hook call. Hooks can only be called inside of the body of a function component.',
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: This is not deterministic since it's created during render.
|
||||
return (
|
||||
responseState.opaqueIdentifierPrefix +
|
||||
(responseState.nextOpaqueID++).toString(36)
|
||||
);
|
||||
}
|
||||
|
||||
function encodeHTMLTextNode(text: string): string {
|
||||
return escapeTextForBrowser(text);
|
||||
}
|
||||
|
||||
@@ -34,9 +34,7 @@ export type ResponseState = {
|
||||
placeholderPrefix: PrecomputedChunk,
|
||||
segmentPrefix: PrecomputedChunk,
|
||||
boundaryPrefix: string,
|
||||
opaqueIdentifierPrefix: string,
|
||||
nextSuspenseID: number,
|
||||
nextOpaqueID: number,
|
||||
sentCompleteSegmentFunction: boolean,
|
||||
sentCompleteBoundaryFunction: boolean,
|
||||
sentClientRenderFunction: boolean,
|
||||
@@ -56,9 +54,7 @@ export function createResponseState(
|
||||
placeholderPrefix: responseState.placeholderPrefix,
|
||||
segmentPrefix: responseState.segmentPrefix,
|
||||
boundaryPrefix: responseState.boundaryPrefix,
|
||||
opaqueIdentifierPrefix: responseState.opaqueIdentifierPrefix,
|
||||
nextSuspenseID: responseState.nextSuspenseID,
|
||||
nextOpaqueID: responseState.nextOpaqueID,
|
||||
sentCompleteSegmentFunction: responseState.sentCompleteSegmentFunction,
|
||||
sentCompleteBoundaryFunction: responseState.sentCompleteBoundaryFunction,
|
||||
sentClientRenderFunction: responseState.sentClientRenderFunction,
|
||||
@@ -77,14 +73,12 @@ export function createRootFormatContext(): FormatContext {
|
||||
export type {
|
||||
FormatContext,
|
||||
SuspenseBoundaryID,
|
||||
OpaqueIDType,
|
||||
} from './ReactDOMServerFormatConfig';
|
||||
|
||||
export {
|
||||
getChildFormatContext,
|
||||
UNINITIALIZED_SUSPENSE_BOUNDARY_ID,
|
||||
assignSuspenseBoundaryID,
|
||||
makeServerID,
|
||||
pushStartInstance,
|
||||
pushEndInstance,
|
||||
pushStartCompletedSuspenseBoundary,
|
||||
|
||||
+1
-16
@@ -82,10 +82,6 @@ import {validateProperties as validateInputProperties} from '../shared/ReactDOMN
|
||||
import {validateProperties as validateUnknownProperties} from '../shared/ReactDOMUnknownPropertyHook';
|
||||
import hasOwnProperty from 'shared/hasOwnProperty';
|
||||
|
||||
export type ServerOptions = {
|
||||
identifierPrefix?: string,
|
||||
};
|
||||
|
||||
// Based on reading the React.Children implementation. TODO: type this somewhere?
|
||||
type ReactNode = string | number | ReactElement;
|
||||
type FlatReactChildren = Array<null | ReactNode>;
|
||||
@@ -784,14 +780,7 @@ class ReactDOMServerRenderer {
|
||||
contextValueStack: Array<any>;
|
||||
contextProviderStack: ?Array<ReactProvider<any>>; // DEV-only
|
||||
|
||||
uniqueID: number;
|
||||
identifierPrefix: string;
|
||||
|
||||
constructor(
|
||||
children: mixed,
|
||||
makeStaticMarkup: boolean,
|
||||
options?: ServerOptions,
|
||||
) {
|
||||
constructor(children: mixed, makeStaticMarkup: boolean) {
|
||||
const flatChildren = flattenTopLevelChildren(children);
|
||||
|
||||
const topFrame: Frame = {
|
||||
@@ -820,10 +809,6 @@ class ReactDOMServerRenderer {
|
||||
this.contextStack = [];
|
||||
this.contextValueStack = [];
|
||||
|
||||
// useOpaqueIdentifier ID
|
||||
this.uniqueID = 0;
|
||||
this.identifierPrefix = (options && options.identifierPrefix) || '';
|
||||
|
||||
if (__DEV__) {
|
||||
this.contextProviderStack = [];
|
||||
}
|
||||
|
||||
+1
-12
@@ -41,8 +41,6 @@ type Hook = {|
|
||||
next: Hook | null,
|
||||
|};
|
||||
|
||||
type OpaqueIDType = string;
|
||||
|
||||
let currentlyRenderingComponent: Object | null = null;
|
||||
let firstWorkInProgressHook: Hook | null = null;
|
||||
let workInProgressHook: Hook | null = null;
|
||||
@@ -511,15 +509,7 @@ function useTransition(): [boolean, (callback: () => void) => void] {
|
||||
return [false, startTransition];
|
||||
}
|
||||
|
||||
function useOpaqueIdentifier(): OpaqueIDType {
|
||||
return (
|
||||
(currentPartialRenderer.identifierPrefix || '') +
|
||||
'R:' +
|
||||
(currentPartialRenderer.uniqueID++).toString(36)
|
||||
);
|
||||
}
|
||||
|
||||
function useId(): OpaqueIDType {
|
||||
function useId(): string {
|
||||
throw new Error('Not implemented.');
|
||||
}
|
||||
|
||||
@@ -552,7 +542,6 @@ export const Dispatcher: DispatcherType = {
|
||||
useDebugValue: noop,
|
||||
useDeferredValue,
|
||||
useTransition,
|
||||
useOpaqueIdentifier,
|
||||
useId,
|
||||
// Subscriptions are not setup in a server environment.
|
||||
useMutableSource,
|
||||
|
||||
@@ -84,8 +84,6 @@ export type UpdatePayload = Object;
|
||||
export type TimeoutHandle = TimeoutID;
|
||||
export type NoTimeout = -1;
|
||||
|
||||
export type OpaqueIDType = void;
|
||||
|
||||
export type RendererInspectionConfig = $ReadOnly<{|
|
||||
// Deprecated. Replaced with getInspectorDataForViewAtPoint.
|
||||
getInspectorDataForViewTag?: (tag: number) => Object,
|
||||
@@ -512,24 +510,6 @@ export function getInstanceFromNode(node: any) {
|
||||
throw new Error('Not yet implemented.');
|
||||
}
|
||||
|
||||
export function isOpaqueHydratingObject(value: mixed): boolean {
|
||||
throw new Error('Not yet implemented');
|
||||
}
|
||||
|
||||
export function makeOpaqueHydratingObject(
|
||||
attemptToReadValue: () => void,
|
||||
): OpaqueIDType {
|
||||
throw new Error('Not yet implemented.');
|
||||
}
|
||||
|
||||
export function makeClientId(): OpaqueIDType {
|
||||
throw new Error('Not yet implemented');
|
||||
}
|
||||
|
||||
export function makeClientIdInDEV(warnOnAccessInDEV: () => void): OpaqueIDType {
|
||||
throw new Error('Not yet implemented');
|
||||
}
|
||||
|
||||
export function beforeActiveInstanceBlur(internalInstanceHandle: Object) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ export type ChildSet = void; // Unused
|
||||
|
||||
export type TimeoutHandle = TimeoutID;
|
||||
export type NoTimeout = -1;
|
||||
export type OpaqueIDType = void;
|
||||
|
||||
export type RendererInspectionConfig = $ReadOnly<{|
|
||||
// Deprecated. Replaced with getInspectorDataForViewAtPoint.
|
||||
@@ -499,24 +498,6 @@ export function getInstanceFromNode(node: any) {
|
||||
throw new Error('Not yet implemented.');
|
||||
}
|
||||
|
||||
export function isOpaqueHydratingObject(value: mixed): boolean {
|
||||
throw new Error('Not yet implemented');
|
||||
}
|
||||
|
||||
export function makeOpaqueHydratingObject(
|
||||
attemptToReadValue: () => void,
|
||||
): OpaqueIDType {
|
||||
throw new Error('Not yet implemented.');
|
||||
}
|
||||
|
||||
export function makeClientId(): OpaqueIDType {
|
||||
throw new Error('Not yet implemented');
|
||||
}
|
||||
|
||||
export function makeClientIdInDEV(warnOnAccessInDEV: () => void): OpaqueIDType {
|
||||
throw new Error('Not yet implemented');
|
||||
}
|
||||
|
||||
export function beforeActiveInstanceBlur(internalInstanceHandle: Object) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -59,14 +59,12 @@ SUSPENSE_UPDATE_TO_CLIENT_RENDER[0] = SUSPENSE_UPDATE_TO_CLIENT_RENDER_TAG;
|
||||
// Per response,
|
||||
export type ResponseState = {
|
||||
nextSuspenseID: number,
|
||||
nextOpaqueID: number,
|
||||
};
|
||||
|
||||
// Allows us to keep track of what we've already written so we can refer back to it.
|
||||
export function createResponseState(): ResponseState {
|
||||
return {
|
||||
nextSuspenseID: 0,
|
||||
nextOpaqueID: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -109,21 +107,6 @@ export function assignSuspenseBoundaryID(
|
||||
return responseState.nextSuspenseID++;
|
||||
}
|
||||
|
||||
export type OpaqueIDType = number;
|
||||
|
||||
export function makeServerID(
|
||||
responseState: null | ResponseState,
|
||||
): OpaqueIDType {
|
||||
if (responseState === null) {
|
||||
throw new Error(
|
||||
'Invalid hook call. Hooks can only be called inside of the body of a function component.',
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: This is not deterministic since it's created during render.
|
||||
return responseState.nextOpaqueID++;
|
||||
}
|
||||
|
||||
const RAW_TEXT = stringToPrecomputedChunk('RCTRawText');
|
||||
|
||||
export function pushTextInstance(
|
||||
|
||||
@@ -53,8 +53,6 @@ type Destination = {
|
||||
|
||||
const POP = Buffer.from('/', 'utf8');
|
||||
|
||||
let opaqueID = 0;
|
||||
|
||||
const ReactNoopServer = ReactFizzServer({
|
||||
scheduleWork(callback: () => void) {
|
||||
callback();
|
||||
@@ -88,10 +86,6 @@ const ReactNoopServer = ReactFizzServer({
|
||||
return {state: 'pending', children: []};
|
||||
},
|
||||
|
||||
makeServerID(): number {
|
||||
return opaqueID++;
|
||||
},
|
||||
|
||||
getChildFormatContext(): null {
|
||||
return null;
|
||||
},
|
||||
|
||||
@@ -17,7 +17,6 @@ import type {Fiber, Dispatcher, HookType} from './ReactInternalTypes';
|
||||
import type {Lanes, Lane} from './ReactFiberLane.new';
|
||||
import type {HookFlags} from './ReactHookEffectTags';
|
||||
import type {FiberRoot} from './ReactInternalTypes';
|
||||
import type {OpaqueIDType} from './ReactFiberHostConfig';
|
||||
import type {Cache} from './ReactFiberCacheComponent.new';
|
||||
import type {Flags} from './ReactFiberFlags';
|
||||
|
||||
@@ -95,18 +94,12 @@ import {
|
||||
checkIfWorkInProgressReceivedUpdate,
|
||||
} from './ReactFiberBeginWork.new';
|
||||
import {getIsHydrating} from './ReactFiberHydrationContext.new';
|
||||
import {
|
||||
makeClientId,
|
||||
makeClientIdInDEV,
|
||||
makeOpaqueHydratingObject,
|
||||
} from './ReactFiberHostConfig';
|
||||
import {
|
||||
getWorkInProgressVersion,
|
||||
markSourceAsDirty,
|
||||
setWorkInProgressVersion,
|
||||
warnAboutMultipleRenderersDEV,
|
||||
} from './ReactMutableSource.new';
|
||||
import {getIsRendering} from './ReactCurrentFiber';
|
||||
import {logStateUpdateScheduled} from './DebugTracing';
|
||||
import {markStateUpdateScheduled} from './SchedulingProfiler';
|
||||
import {createCache, CacheContext} from './ReactFiberCacheComponent.new';
|
||||
@@ -139,10 +132,8 @@ export type UpdateQueue<S, A> = {|
|
||||
|};
|
||||
|
||||
let didWarnAboutMismatchedHooksForComponent;
|
||||
let didWarnAboutUseOpaqueIdentifier;
|
||||
let didWarnUncachedGetSnapshot;
|
||||
if (__DEV__) {
|
||||
didWarnAboutUseOpaqueIdentifier = {};
|
||||
didWarnAboutMismatchedHooksForComponent = new Set();
|
||||
}
|
||||
|
||||
@@ -2045,94 +2036,6 @@ export function getIsUpdatingOpaqueValueInRenderPhaseInDEV(): boolean | void {
|
||||
}
|
||||
}
|
||||
|
||||
function warnOnOpaqueIdentifierAccessInDEV(fiber) {
|
||||
if (__DEV__) {
|
||||
// TODO: Should warn in effects and callbacks, too
|
||||
const name = getComponentNameFromFiber(fiber) || 'Unknown';
|
||||
if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) {
|
||||
console.error(
|
||||
'The object passed back from useOpaqueIdentifier is meant to be ' +
|
||||
'passed through to attributes only. Do not read the ' +
|
||||
'value directly.',
|
||||
);
|
||||
didWarnAboutUseOpaqueIdentifier[name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mountOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const makeId = __DEV__
|
||||
? makeClientIdInDEV.bind(
|
||||
null,
|
||||
warnOnOpaqueIdentifierAccessInDEV.bind(null, currentlyRenderingFiber),
|
||||
)
|
||||
: makeClientId;
|
||||
|
||||
if (getIsHydrating()) {
|
||||
let didUpgrade = false;
|
||||
const fiber = currentlyRenderingFiber;
|
||||
const readValue = () => {
|
||||
if (!didUpgrade) {
|
||||
// Only upgrade once. This works even inside the render phase because
|
||||
// the update is added to a shared queue, which outlasts the
|
||||
// in-progress render.
|
||||
didUpgrade = true;
|
||||
if (__DEV__) {
|
||||
isUpdatingOpaqueValueInRenderPhase = true;
|
||||
setId(makeId());
|
||||
isUpdatingOpaqueValueInRenderPhase = false;
|
||||
warnOnOpaqueIdentifierAccessInDEV(fiber);
|
||||
} else {
|
||||
setId(makeId());
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
'The object passed back from useOpaqueIdentifier is meant to be ' +
|
||||
'passed through to attributes only. Do not read the value directly.',
|
||||
);
|
||||
};
|
||||
const id = makeOpaqueHydratingObject(readValue);
|
||||
|
||||
const setId = mountState(id)[1];
|
||||
|
||||
if ((currentlyRenderingFiber.mode & ConcurrentMode) === NoMode) {
|
||||
if (
|
||||
__DEV__ &&
|
||||
enableStrictEffects &&
|
||||
(currentlyRenderingFiber.mode & StrictEffectsMode) === NoMode
|
||||
) {
|
||||
currentlyRenderingFiber.flags |= MountPassiveDevEffect | PassiveEffect;
|
||||
} else {
|
||||
currentlyRenderingFiber.flags |= PassiveEffect;
|
||||
}
|
||||
pushEffect(
|
||||
HookHasEffect | HookPassive,
|
||||
() => {
|
||||
setId(makeId());
|
||||
},
|
||||
undefined,
|
||||
null,
|
||||
);
|
||||
}
|
||||
return id;
|
||||
} else {
|
||||
const id = makeId();
|
||||
mountState(id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
function updateOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const id = updateState(undefined)[0];
|
||||
return id;
|
||||
}
|
||||
|
||||
function rerenderOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const id = rerenderState(undefined)[0];
|
||||
return id;
|
||||
}
|
||||
|
||||
function mountId(): string {
|
||||
const hook = mountWorkInProgressHook();
|
||||
|
||||
@@ -2481,7 +2384,6 @@ export const ContextOnlyDispatcher: Dispatcher = {
|
||||
useTransition: throwInvalidHookError,
|
||||
useMutableSource: throwInvalidHookError,
|
||||
useSyncExternalStore: throwInvalidHookError,
|
||||
useOpaqueIdentifier: throwInvalidHookError,
|
||||
useId: throwInvalidHookError,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2510,7 +2412,6 @@ const HooksDispatcherOnMount: Dispatcher = {
|
||||
useTransition: mountTransition,
|
||||
useMutableSource: mountMutableSource,
|
||||
useSyncExternalStore: mountSyncExternalStore,
|
||||
useOpaqueIdentifier: mountOpaqueIdentifier,
|
||||
useId: mountId,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2539,7 +2440,6 @@ const HooksDispatcherOnUpdate: Dispatcher = {
|
||||
useTransition: updateTransition,
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: updateSyncExternalStore,
|
||||
useOpaqueIdentifier: updateOpaqueIdentifier,
|
||||
useId: updateId,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2568,7 +2468,6 @@ const HooksDispatcherOnRerender: Dispatcher = {
|
||||
useTransition: rerenderTransition,
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: mountSyncExternalStore,
|
||||
useOpaqueIdentifier: rerenderOpaqueIdentifier,
|
||||
useId: updateId,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2736,11 +2635,6 @@ if (__DEV__) {
|
||||
mountHookTypesDev();
|
||||
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
mountHookTypesDev();
|
||||
return mountOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
mountHookTypesDev();
|
||||
@@ -2883,11 +2777,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
updateHookTypesDev();
|
||||
return mountOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
updateHookTypesDev();
|
||||
@@ -3030,11 +2919,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
updateHookTypesDev();
|
||||
return updateOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
updateHookTypesDev();
|
||||
@@ -3178,11 +3062,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
updateHookTypesDev();
|
||||
return rerenderOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
updateHookTypesDev();
|
||||
@@ -3341,12 +3220,6 @@ if (__DEV__) {
|
||||
mountHookTypesDev();
|
||||
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
warnInvalidHookAccess();
|
||||
mountHookTypesDev();
|
||||
return mountOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
warnInvalidHookAccess();
|
||||
@@ -3506,12 +3379,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return updateOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
warnInvalidHookAccess();
|
||||
@@ -3672,12 +3539,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return rerenderOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
warnInvalidHookAccess();
|
||||
|
||||
@@ -17,7 +17,6 @@ import type {Fiber, Dispatcher, HookType} from './ReactInternalTypes';
|
||||
import type {Lanes, Lane} from './ReactFiberLane.old';
|
||||
import type {HookFlags} from './ReactHookEffectTags';
|
||||
import type {FiberRoot} from './ReactInternalTypes';
|
||||
import type {OpaqueIDType} from './ReactFiberHostConfig';
|
||||
import type {Cache} from './ReactFiberCacheComponent.old';
|
||||
import type {Flags} from './ReactFiberFlags';
|
||||
|
||||
@@ -95,18 +94,12 @@ import {
|
||||
checkIfWorkInProgressReceivedUpdate,
|
||||
} from './ReactFiberBeginWork.old';
|
||||
import {getIsHydrating} from './ReactFiberHydrationContext.old';
|
||||
import {
|
||||
makeClientId,
|
||||
makeClientIdInDEV,
|
||||
makeOpaqueHydratingObject,
|
||||
} from './ReactFiberHostConfig';
|
||||
import {
|
||||
getWorkInProgressVersion,
|
||||
markSourceAsDirty,
|
||||
setWorkInProgressVersion,
|
||||
warnAboutMultipleRenderersDEV,
|
||||
} from './ReactMutableSource.old';
|
||||
import {getIsRendering} from './ReactCurrentFiber';
|
||||
import {logStateUpdateScheduled} from './DebugTracing';
|
||||
import {markStateUpdateScheduled} from './SchedulingProfiler';
|
||||
import {createCache, CacheContext} from './ReactFiberCacheComponent.old';
|
||||
@@ -139,10 +132,8 @@ export type UpdateQueue<S, A> = {|
|
||||
|};
|
||||
|
||||
let didWarnAboutMismatchedHooksForComponent;
|
||||
let didWarnAboutUseOpaqueIdentifier;
|
||||
let didWarnUncachedGetSnapshot;
|
||||
if (__DEV__) {
|
||||
didWarnAboutUseOpaqueIdentifier = {};
|
||||
didWarnAboutMismatchedHooksForComponent = new Set();
|
||||
}
|
||||
|
||||
@@ -2045,94 +2036,6 @@ export function getIsUpdatingOpaqueValueInRenderPhaseInDEV(): boolean | void {
|
||||
}
|
||||
}
|
||||
|
||||
function warnOnOpaqueIdentifierAccessInDEV(fiber) {
|
||||
if (__DEV__) {
|
||||
// TODO: Should warn in effects and callbacks, too
|
||||
const name = getComponentNameFromFiber(fiber) || 'Unknown';
|
||||
if (getIsRendering() && !didWarnAboutUseOpaqueIdentifier[name]) {
|
||||
console.error(
|
||||
'The object passed back from useOpaqueIdentifier is meant to be ' +
|
||||
'passed through to attributes only. Do not read the ' +
|
||||
'value directly.',
|
||||
);
|
||||
didWarnAboutUseOpaqueIdentifier[name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mountOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const makeId = __DEV__
|
||||
? makeClientIdInDEV.bind(
|
||||
null,
|
||||
warnOnOpaqueIdentifierAccessInDEV.bind(null, currentlyRenderingFiber),
|
||||
)
|
||||
: makeClientId;
|
||||
|
||||
if (getIsHydrating()) {
|
||||
let didUpgrade = false;
|
||||
const fiber = currentlyRenderingFiber;
|
||||
const readValue = () => {
|
||||
if (!didUpgrade) {
|
||||
// Only upgrade once. This works even inside the render phase because
|
||||
// the update is added to a shared queue, which outlasts the
|
||||
// in-progress render.
|
||||
didUpgrade = true;
|
||||
if (__DEV__) {
|
||||
isUpdatingOpaqueValueInRenderPhase = true;
|
||||
setId(makeId());
|
||||
isUpdatingOpaqueValueInRenderPhase = false;
|
||||
warnOnOpaqueIdentifierAccessInDEV(fiber);
|
||||
} else {
|
||||
setId(makeId());
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
'The object passed back from useOpaqueIdentifier is meant to be ' +
|
||||
'passed through to attributes only. Do not read the value directly.',
|
||||
);
|
||||
};
|
||||
const id = makeOpaqueHydratingObject(readValue);
|
||||
|
||||
const setId = mountState(id)[1];
|
||||
|
||||
if ((currentlyRenderingFiber.mode & ConcurrentMode) === NoMode) {
|
||||
if (
|
||||
__DEV__ &&
|
||||
enableStrictEffects &&
|
||||
(currentlyRenderingFiber.mode & StrictEffectsMode) === NoMode
|
||||
) {
|
||||
currentlyRenderingFiber.flags |= MountPassiveDevEffect | PassiveEffect;
|
||||
} else {
|
||||
currentlyRenderingFiber.flags |= PassiveEffect;
|
||||
}
|
||||
pushEffect(
|
||||
HookHasEffect | HookPassive,
|
||||
() => {
|
||||
setId(makeId());
|
||||
},
|
||||
undefined,
|
||||
null,
|
||||
);
|
||||
}
|
||||
return id;
|
||||
} else {
|
||||
const id = makeId();
|
||||
mountState(id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
function updateOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const id = updateState(undefined)[0];
|
||||
return id;
|
||||
}
|
||||
|
||||
function rerenderOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const id = rerenderState(undefined)[0];
|
||||
return id;
|
||||
}
|
||||
|
||||
function mountId(): string {
|
||||
const hook = mountWorkInProgressHook();
|
||||
|
||||
@@ -2481,7 +2384,6 @@ export const ContextOnlyDispatcher: Dispatcher = {
|
||||
useTransition: throwInvalidHookError,
|
||||
useMutableSource: throwInvalidHookError,
|
||||
useSyncExternalStore: throwInvalidHookError,
|
||||
useOpaqueIdentifier: throwInvalidHookError,
|
||||
useId: throwInvalidHookError,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2510,7 +2412,6 @@ const HooksDispatcherOnMount: Dispatcher = {
|
||||
useTransition: mountTransition,
|
||||
useMutableSource: mountMutableSource,
|
||||
useSyncExternalStore: mountSyncExternalStore,
|
||||
useOpaqueIdentifier: mountOpaqueIdentifier,
|
||||
useId: mountId,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2539,7 +2440,6 @@ const HooksDispatcherOnUpdate: Dispatcher = {
|
||||
useTransition: updateTransition,
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: updateSyncExternalStore,
|
||||
useOpaqueIdentifier: updateOpaqueIdentifier,
|
||||
useId: updateId,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2568,7 +2468,6 @@ const HooksDispatcherOnRerender: Dispatcher = {
|
||||
useTransition: rerenderTransition,
|
||||
useMutableSource: updateMutableSource,
|
||||
useSyncExternalStore: mountSyncExternalStore,
|
||||
useOpaqueIdentifier: rerenderOpaqueIdentifier,
|
||||
useId: updateId,
|
||||
|
||||
unstable_isNewReconciler: enableNewReconciler,
|
||||
@@ -2736,11 +2635,6 @@ if (__DEV__) {
|
||||
mountHookTypesDev();
|
||||
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
mountHookTypesDev();
|
||||
return mountOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
mountHookTypesDev();
|
||||
@@ -2883,11 +2777,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
updateHookTypesDev();
|
||||
return mountOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
updateHookTypesDev();
|
||||
@@ -3030,11 +2919,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
updateHookTypesDev();
|
||||
return updateOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
updateHookTypesDev();
|
||||
@@ -3178,11 +3062,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
updateHookTypesDev();
|
||||
return rerenderOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
updateHookTypesDev();
|
||||
@@ -3341,12 +3220,6 @@ if (__DEV__) {
|
||||
mountHookTypesDev();
|
||||
return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
warnInvalidHookAccess();
|
||||
mountHookTypesDev();
|
||||
return mountOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
warnInvalidHookAccess();
|
||||
@@ -3506,12 +3379,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return updateOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
warnInvalidHookAccess();
|
||||
@@ -3672,12 +3539,6 @@ if (__DEV__) {
|
||||
updateHookTypesDev();
|
||||
return updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
},
|
||||
useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
currentHookNameInDev = 'useOpaqueIdentifier';
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
return rerenderOpaqueIdentifier();
|
||||
},
|
||||
useId(): string {
|
||||
currentHookNameInDev = 'useId';
|
||||
warnInvalidHookAccess();
|
||||
|
||||
@@ -474,8 +474,7 @@ export function scheduleUpdateOnFiber(
|
||||
// if the update originates from user space (with the exception of local
|
||||
// hook updates, which are handled differently and don't reach this
|
||||
// function), but there are some internal React features that use this as
|
||||
// an implementation detail, like selective hydration
|
||||
// and useOpaqueIdentifier.
|
||||
// an implementation detail, like selective hydration.
|
||||
warnAboutRenderPhaseUpdatesInDEV(fiber);
|
||||
|
||||
// Track lanes that were updated during the render phase
|
||||
@@ -898,12 +897,10 @@ function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
exitStatus === RootErrored &&
|
||||
workInProgressRootRenderPhaseUpdatedLanes !== NoLanes
|
||||
) {
|
||||
// There was a render phase update during this render. This was likely a
|
||||
// useOpaqueIdentifier hook upgrading itself to a client ID. Try rendering
|
||||
// again. This time, the component will use a client ID and will proceed
|
||||
// without throwing. If multiple IDs upgrade as a result of the same
|
||||
// update, we will have to do multiple render passes. To protect against
|
||||
// an inifinite loop, eventually we'll give up.
|
||||
// There was a render phase update during this render. Some internal React
|
||||
// implementation details may use this as a trick to schedule another
|
||||
// render pass. To protect against an inifinite loop, eventually
|
||||
// we'll give up.
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -474,8 +474,7 @@ export function scheduleUpdateOnFiber(
|
||||
// if the update originates from user space (with the exception of local
|
||||
// hook updates, which are handled differently and don't reach this
|
||||
// function), but there are some internal React features that use this as
|
||||
// an implementation detail, like selective hydration
|
||||
// and useOpaqueIdentifier.
|
||||
// an implementation detail, like selective hydration.
|
||||
warnAboutRenderPhaseUpdatesInDEV(fiber);
|
||||
|
||||
// Track lanes that were updated during the render phase
|
||||
@@ -898,12 +897,10 @@ function recoverFromConcurrentError(root, errorRetryLanes) {
|
||||
exitStatus === RootErrored &&
|
||||
workInProgressRootRenderPhaseUpdatedLanes !== NoLanes
|
||||
) {
|
||||
// There was a render phase update during this render. This was likely a
|
||||
// useOpaqueIdentifier hook upgrading itself to a client ID. Try rendering
|
||||
// again. This time, the component will use a client ID and will proceed
|
||||
// without throwing. If multiple IDs upgrade as a result of the same
|
||||
// update, we will have to do multiple render passes. To protect against
|
||||
// an inifinite loop, eventually we'll give up.
|
||||
// There was a render phase update during this render. Some internal React
|
||||
// implementation details may use this as a trick to schedule another
|
||||
// render pass. To protect against an inifinite loop, eventually
|
||||
// we'll give up.
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -43,7 +43,6 @@ export type HookType =
|
||||
| 'useTransition'
|
||||
| 'useMutableSource'
|
||||
| 'useSyncExternalStore'
|
||||
| 'useOpaqueIdentifier'
|
||||
| 'useId'
|
||||
| 'useCacheRefresh';
|
||||
|
||||
@@ -317,7 +316,6 @@ export type Dispatcher = {|
|
||||
getSnapshot: () => T,
|
||||
getServerSnapshot?: () => T,
|
||||
): T,
|
||||
useOpaqueIdentifier(): any,
|
||||
useId(): string,
|
||||
useCacheRefresh?: () => <T>(?() => T, ?T) => void,
|
||||
|
||||
|
||||
+8
-8
@@ -1916,14 +1916,14 @@ describe('ReactIncrementalErrorHandling', () => {
|
||||
});
|
||||
|
||||
it("does not infinite loop if there's a render phase update in the same render as an error", async () => {
|
||||
// useOpaqueIdentifier uses an render phase update as an implementation
|
||||
// detail. When an error is accompanied by a render phase update, we assume
|
||||
// that it comes from useOpaqueIdentifier, because render phase updates
|
||||
// triggered from userspace are not allowed (we log a warning). So we keep
|
||||
// attempting to recover until no more opaque identifiers need to be
|
||||
// upgraded. However, we should give up after some point to prevent an
|
||||
// infinite loop in the case where there is (by accident) a render phase
|
||||
// triggered from userspace.
|
||||
// Some React features may schedule a render phase update as an
|
||||
// implementation detail. When an error is accompanied by a render phase
|
||||
// update, we assume that it comes from React internals, because render
|
||||
// phase updates triggered from userspace are not allowed (we log a
|
||||
// warning). So we keep attempting to recover until no more opaque
|
||||
// identifiers need to be upgraded. However, we should give up after some
|
||||
// point to prevent an infinite loop in the case where there is (by
|
||||
// accident) a render phase triggered from userspace.
|
||||
|
||||
spyOnDev(console, 'error');
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ export opaque type ChildSet = mixed; // eslint-disable-line no-undef
|
||||
export opaque type TimeoutHandle = mixed; // eslint-disable-line no-undef
|
||||
export opaque type NoTimeout = mixed; // eslint-disable-line no-undef
|
||||
export opaque type RendererInspectionConfig = mixed; // eslint-disable-line no-undef
|
||||
export opaque type OpaqueIDType = mixed;
|
||||
export type EventResponder = any;
|
||||
|
||||
export const getPublicInstance = $$$hostConfig.getPublicInstance;
|
||||
@@ -62,11 +61,6 @@ export const supportsMutation = $$$hostConfig.supportsMutation;
|
||||
export const supportsPersistence = $$$hostConfig.supportsPersistence;
|
||||
export const supportsHydration = $$$hostConfig.supportsHydration;
|
||||
export const getInstanceFromNode = $$$hostConfig.getInstanceFromNode;
|
||||
export const isOpaqueHydratingObject = $$$hostConfig.isOpaqueHydratingObject;
|
||||
export const makeOpaqueHydratingObject =
|
||||
$$$hostConfig.makeOpaqueHydratingObject;
|
||||
export const makeClientId = $$$hostConfig.makeClientId;
|
||||
export const makeClientIdInDEV = $$$hostConfig.makeClientIdInDEV;
|
||||
export const beforeActiveInstanceBlur = $$$hostConfig.beforeActiveInstanceBlur;
|
||||
export const afterActiveInstanceBlur = $$$hostConfig.afterActiveInstanceBlur;
|
||||
export const preparePortalMount = $$$hostConfig.preparePortalMount;
|
||||
|
||||
+1
-8
@@ -16,14 +16,12 @@ import type {
|
||||
ReactContext,
|
||||
} from 'shared/ReactTypes';
|
||||
|
||||
import type {ResponseState, OpaqueIDType} from './ReactServerFormatConfig';
|
||||
import type {ResponseState} from './ReactServerFormatConfig';
|
||||
import type {Task} from './ReactFizzServer';
|
||||
|
||||
import {readContext as readContextImpl} from './ReactFizzNewContext';
|
||||
import {getTreeId} from './ReactFizzTreeContext';
|
||||
|
||||
import {makeServerID} from './ReactServerFormatConfig';
|
||||
|
||||
import {enableCache} from 'shared/ReactFeatureFlags';
|
||||
import is from 'shared/objectIs';
|
||||
|
||||
@@ -509,10 +507,6 @@ function useTransition(): [boolean, (callback: () => void) => void] {
|
||||
return [false, unsupportedStartTransition];
|
||||
}
|
||||
|
||||
function useOpaqueIdentifier(): OpaqueIDType {
|
||||
return makeServerID(currentResponseState);
|
||||
}
|
||||
|
||||
function useId(): string {
|
||||
const task: Task = (currentlyRenderingTask: any);
|
||||
const treeId = getTreeId(task.treeContext);
|
||||
@@ -559,7 +553,6 @@ export const Dispatcher: DispatcherType = {
|
||||
useDebugValue: noop,
|
||||
useDeferredValue,
|
||||
useTransition,
|
||||
useOpaqueIdentifier,
|
||||
useId,
|
||||
// Subscriptions are not setup in a server environment.
|
||||
useMutableSource,
|
||||
|
||||
@@ -845,7 +845,6 @@ const Dispatcher: DispatcherType = {
|
||||
useLayoutEffect: (unsupportedHook: any),
|
||||
useImperativeHandle: (unsupportedHook: any),
|
||||
useEffect: (unsupportedHook: any),
|
||||
useOpaqueIdentifier: (unsupportedHook: any),
|
||||
useId: (unsupportedHook: any),
|
||||
useMutableSource: (unsupportedHook: any),
|
||||
useSyncExternalStore: (unsupportedHook: any),
|
||||
|
||||
@@ -28,7 +28,6 @@ export opaque type Destination = mixed; // eslint-disable-line no-undef
|
||||
export opaque type ResponseState = mixed;
|
||||
export opaque type FormatContext = mixed;
|
||||
export opaque type SuspenseBoundaryID = mixed;
|
||||
export opaque type OpaqueIDType = mixed;
|
||||
|
||||
export const isPrimaryRenderer = false;
|
||||
|
||||
@@ -36,7 +35,6 @@ export const getChildFormatContext = $$$hostConfig.getChildFormatContext;
|
||||
export const UNINITIALIZED_SUSPENSE_BOUNDARY_ID =
|
||||
$$$hostConfig.UNINITIALIZED_SUSPENSE_BOUNDARY_ID;
|
||||
export const assignSuspenseBoundaryID = $$$hostConfig.assignSuspenseBoundaryID;
|
||||
export const makeServerID = $$$hostConfig.makeServerID;
|
||||
export const pushTextInstance = $$$hostConfig.pushTextInstance;
|
||||
export const pushStartInstance = $$$hostConfig.pushStartInstance;
|
||||
export const pushEndInstance = $$$hostConfig.pushEndInstance;
|
||||
|
||||
@@ -42,7 +42,6 @@ export function waitForSuspense<T>(fn: () => T): Promise<T> {
|
||||
useDebugValue: unsupported,
|
||||
useDeferredValue: unsupported,
|
||||
useTransition: unsupported,
|
||||
useOpaqueIdentifier: unsupported,
|
||||
useId: unsupported,
|
||||
useMutableSource: unsupported,
|
||||
useSyncExternalStore: unsupported,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import {REACT_OPAQUE_ID_TYPE} from 'shared/ReactSymbols';
|
||||
import isArray from 'shared/isArray';
|
||||
import {DefaultEventPriority} from 'react-reconciler/src/ReactEventPriorities';
|
||||
|
||||
@@ -40,12 +39,6 @@ export type ChildSet = void; // Unused
|
||||
export type TimeoutHandle = TimeoutID;
|
||||
export type NoTimeout = -1;
|
||||
export type EventResponder = any;
|
||||
export opaque type OpaqueIDType =
|
||||
| string
|
||||
| {
|
||||
toString: () => string | void,
|
||||
valueOf: () => string | void,
|
||||
};
|
||||
|
||||
export type RendererInspectionConfig = $ReadOnly<{||}>;
|
||||
|
||||
@@ -298,43 +291,6 @@ export function getInstanceFromNode(mockNode: Object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let clientId: number = 0;
|
||||
export function makeClientId(): OpaqueIDType {
|
||||
return 'c_' + (clientId++).toString(36);
|
||||
}
|
||||
|
||||
export function makeClientIdInDEV(warnOnAccessInDEV: () => void): OpaqueIDType {
|
||||
const id = 'c_' + (clientId++).toString(36);
|
||||
return {
|
||||
toString() {
|
||||
warnOnAccessInDEV();
|
||||
return id;
|
||||
},
|
||||
valueOf() {
|
||||
warnOnAccessInDEV();
|
||||
return id;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function isOpaqueHydratingObject(value: mixed): boolean {
|
||||
return (
|
||||
value !== null &&
|
||||
typeof value === 'object' &&
|
||||
value.$$typeof === REACT_OPAQUE_ID_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
export function makeOpaqueHydratingObject(
|
||||
attemptToReadValue: () => void,
|
||||
): OpaqueIDType {
|
||||
return {
|
||||
$$typeof: REACT_OPAQUE_ID_TYPE,
|
||||
toString: attemptToReadValue,
|
||||
valueOf: attemptToReadValue,
|
||||
};
|
||||
}
|
||||
|
||||
export function beforeActiveInstanceBlur(internalInstanceHandle: Object) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ export {
|
||||
unstable_getCacheSignal,
|
||||
unstable_getCacheForType,
|
||||
unstable_useCacheRefresh,
|
||||
unstable_useOpaqueIdentifier,
|
||||
unstable_useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
|
||||
@@ -36,7 +36,6 @@ export {
|
||||
unstable_getCacheSignal,
|
||||
unstable_getCacheForType,
|
||||
unstable_useCacheRefresh,
|
||||
unstable_useOpaqueIdentifier,
|
||||
unstable_useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
|
||||
@@ -61,7 +61,6 @@ export {
|
||||
unstable_getCacheSignal,
|
||||
unstable_getCacheForType,
|
||||
unstable_useCacheRefresh,
|
||||
unstable_useOpaqueIdentifier,
|
||||
unstable_useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
|
||||
@@ -39,7 +39,6 @@ export {
|
||||
unstable_getCacheSignal,
|
||||
unstable_getCacheForType,
|
||||
unstable_useCacheRefresh,
|
||||
unstable_useOpaqueIdentifier,
|
||||
unstable_useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
|
||||
@@ -29,7 +29,6 @@ export {
|
||||
lazy,
|
||||
memo,
|
||||
startTransition,
|
||||
unstable_useOpaqueIdentifier,
|
||||
unstable_useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
|
||||
@@ -52,7 +52,6 @@ import {
|
||||
useState,
|
||||
useTransition,
|
||||
useDeferredValue,
|
||||
useOpaqueIdentifier,
|
||||
useId,
|
||||
useCacheRefresh,
|
||||
} from './ReactHooks';
|
||||
@@ -127,7 +126,6 @@ export {
|
||||
REACT_CACHE_TYPE as unstable_Cache,
|
||||
// enableScopeAPI
|
||||
REACT_SCOPE_TYPE as unstable_Scope,
|
||||
useOpaqueIdentifier as unstable_useOpaqueIdentifier,
|
||||
useId as unstable_useId,
|
||||
act,
|
||||
};
|
||||
@@ -14,7 +14,6 @@ import type {
|
||||
MutableSourceSubscribeFn,
|
||||
ReactContext,
|
||||
} from 'shared/ReactTypes';
|
||||
import type {OpaqueIDType} from 'react-reconciler/src/ReactFiberHostConfig';
|
||||
|
||||
import ReactCurrentDispatcher from './ReactCurrentDispatcher';
|
||||
|
||||
@@ -169,11 +168,6 @@ export function useDeferredValue<T>(value: T): T {
|
||||
return dispatcher.useDeferredValue(value);
|
||||
}
|
||||
|
||||
export function useOpaqueIdentifier(): OpaqueIDType | void {
|
||||
const dispatcher = resolveDispatcher();
|
||||
return dispatcher.useOpaqueIdentifier();
|
||||
}
|
||||
|
||||
export function useId(): string {
|
||||
const dispatcher = resolveDispatcher();
|
||||
return dispatcher.useId();
|
||||
|
||||
@@ -27,7 +27,6 @@ export {
|
||||
unstable_DebugTracingMode,
|
||||
unstable_getCacheSignal,
|
||||
unstable_getCacheForType,
|
||||
unstable_useOpaqueIdentifier,
|
||||
unstable_useId,
|
||||
useCallback,
|
||||
useContext,
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import {REACT_OPAQUE_ID_TYPE} from 'shared/ReactSymbols';
|
||||
|
||||
/*
|
||||
* The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
|
||||
* and Temporal.* types. See https://github.com/facebook/react/pull/22064.
|
||||
@@ -35,16 +33,6 @@ function typeName(value: mixed): string {
|
||||
// $FlowFixMe only called in DEV, so void return is not possible.
|
||||
function willCoercionThrow(value: mixed): boolean {
|
||||
if (__DEV__) {
|
||||
if (
|
||||
value !== null &&
|
||||
typeof value === 'object' &&
|
||||
value.$$typeof === REACT_OPAQUE_ID_TYPE
|
||||
) {
|
||||
// OpaqueID type is expected to throw, so React will handle it. Not sure if
|
||||
// it's expected that string coercion will throw, but we'll assume it's OK.
|
||||
// See https://github.com/facebook/react/issues/20127.
|
||||
return;
|
||||
}
|
||||
try {
|
||||
testStringCoercion(value);
|
||||
return false;
|
||||
|
||||
@@ -26,7 +26,6 @@ export let REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
export let REACT_MEMO_TYPE = 0xead3;
|
||||
export let REACT_LAZY_TYPE = 0xead4;
|
||||
export let REACT_SCOPE_TYPE = 0xead7;
|
||||
export let REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
export let REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
|
||||
export let REACT_OFFSCREEN_TYPE = 0xeae2;
|
||||
export let REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
|
||||
@@ -47,7 +46,6 @@ if (typeof Symbol === 'function' && Symbol.for) {
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
|
||||
REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
|
||||
REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
|
||||
|
||||
@@ -342,7 +342,7 @@
|
||||
"352": "React Lazy Components are not yet supported on the server.",
|
||||
"353": "A server block should never encode any other slots. This is a bug in React.",
|
||||
"354": "getInspectorDataForViewAtPoint() is not available in production.",
|
||||
"355": "The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly.",
|
||||
"355": "The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly. (TODO: This feature was never released so we should be able to remove this error from the map.)",
|
||||
"356": "Could not read the cache.",
|
||||
"357": "The current renderer does not support React Scopes. This error is likely caused by a bug in React. Please file an issue.",
|
||||
"358": "Invalid update priority: %s. This is a bug in React.",
|
||||
|
||||
Reference in new issue
Block a user