UNPKG

44.5 kBTypeScriptView Raw
1import { Component, ReactNode } from "react";
2
3/* eslint-disable @definitelytyped/no-unnecessary-generics */
4declare function ReactReconciler<
5 Type,
6 Props,
7 Container,
8 Instance,
9 TextInstance,
10 SuspenseInstance,
11 HydratableInstance,
12 PublicInstance,
13 HostContext,
14 UpdatePayload,
15 ChildSet,
16 TimeoutHandle,
17 NoTimeout,
18>(
19 /* eslint-enable @definitelytyped/no-unnecessary-generics */
20 config: ReactReconciler.HostConfig<
21 Type,
22 Props,
23 Container,
24 Instance,
25 TextInstance,
26 SuspenseInstance,
27 HydratableInstance,
28 PublicInstance,
29 HostContext,
30 UpdatePayload,
31 ChildSet,
32 TimeoutHandle,
33 NoTimeout
34 >,
35): ReactReconciler.Reconciler<Container, Instance, TextInstance, SuspenseInstance, PublicInstance>;
36
37declare namespace ReactReconciler {
38 interface HostConfig<
39 Type,
40 Props,
41 Container,
42 Instance,
43 TextInstance,
44 SuspenseInstance,
45 HydratableInstance,
46 PublicInstance,
47 HostContext,
48 UpdatePayload,
49 ChildSet,
50 TimeoutHandle,
51 NoTimeout,
52 > {
53 // -------------------
54 // Modes
55 // -------------------
56 /**
57 * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.
58 *
59 * If your target platform is similar to the DOM and has methods similar to `appendChild`, `removeChild`, and so on, you'll want to use the **mutation mode**. This is the same mode used by React DOM, React ART, and the classic React Native renderer.
60 *
61 * ```js
62 * const HostConfig = {
63 * // ...
64 * supportsMutation: true,
65 * // ...
66 * }
67 * ```
68 *
69 * Depending on the mode, the reconciler will call different methods on your host config.
70 *
71 * If you're not sure which one you want, you likely need the mutation mode.
72 */
73 supportsMutation: boolean;
74
75 /**
76 * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.
77 *
78 * If your target platform has immutable trees, you'll want the **persistent mode** instead. In that mode, existing nodes are never mutated, and instead every change clones the parent tree and then replaces the whole parent tree at the root. This is the node used by the new React Native renderer, codenamed "Fabric".
79 *
80 * ```js
81 * const HostConfig = {
82 * // ...
83 * supportsPersistence: true,
84 * // ...
85 * }
86 * ```
87 *
88 * Depending on the mode, the reconciler will call different methods on your host config.
89 *
90 * If you're not sure which one you want, you likely need the mutation mode.
91 */
92 supportsPersistence: boolean;
93
94 // -------------------
95 // Core Methods
96 // -------------------
97
98 /**
99 * This method should return a newly created node. For example, the DOM renderer would call `document.createElement(type)` here and then set the properties from `props`.
100 *
101 * You can use `rootContainer` to access the root container associated with that tree. For example, in the DOM renderer, this is useful to get the correct `document` reference that the root belongs to.
102 *
103 * The `hostContext` parameter lets you keep track of some information about your current place in the tree. To learn more about it, see `getChildHostContext` below.
104 *
105 * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields, be aware that it may change significantly between versions. You're taking on additional maintenance risk by reading from it, and giving up all guarantees if you write something to it.
106 *
107 * This method happens **in the render phase**. It can (and usually should) mutate the node it has just created before returning it, but it must not modify any other nodes. It must not register any event handlers on the parent tree. This is because an instance being created doesn't guarantee it would be placed in the tree — it could be left unused and later collected by GC. If you need to do something when an instance is definitely in the tree, look at `commitMount` instead.
108 */
109 createInstance(
110 type: Type,
111 props: Props,
112 rootContainer: Container,
113 hostContext: HostContext,
114 internalHandle: OpaqueHandle,
115 ): Instance;
116
117 /**
118 * Same as `createInstance`, but for text nodes. If your renderer doesn't support text nodes, you can throw here.
119 */
120 createTextInstance(
121 text: string,
122 rootContainer: Container,
123 hostContext: HostContext,
124 internalHandle: OpaqueHandle,
125 ): TextInstance;
126
127 /**
128 * This method should mutate the `parentInstance` and add the child to its list of children. For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.
129 *
130 * This method happens **in the render phase**. It can mutate `parentInstance` and `child`, but it must not modify any other nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.
131 */
132 appendInitialChild(parentInstance: Instance, child: Instance | TextInstance): void;
133
134 /**
135 * In this method, you can perform some final mutations on the `instance`. Unlike with `createInstance`, by the time `finalizeInitialChildren` is called, all the initial children have already been added to the `instance`, but the instance itself has not yet been connected to the tree on the screen.
136 *
137 * This method happens **in the render phase**. It can mutate `instance`, but it must not modify any other nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.
138 *
139 * There is a second purpose to this method. It lets you specify whether there is some work that needs to happen when the node is connected to the tree on the screen. If you return `true`, the instance will receive a `commitMount` call later. See its documentation below.
140 *
141 * If you don't want to do anything here, you should return `false`.
142 */
143 finalizeInitialChildren(
144 instance: Instance,
145 type: Type,
146 props: Props,
147 rootContainer: Container,
148 hostContext: HostContext,
149 ): boolean;
150
151 /**
152 * React calls this method so that you can compare the previous and the next props, and decide whether you need to update the underlying instance or not. If you don't need to update it, return `null`. If you need to update it, you can return an arbitrary object representing the changes that need to happen. Then in `commitUpdate` you would need to apply those changes to the instance.
153 *
154 * This method happens **in the render phase**. It should only *calculate* the update — but not apply it! For example, the DOM renderer returns an array that looks like `[prop1, value1, prop2, value2, ...]` for all props that have actually changed. And only in `commitUpdate` it applies those changes. You should calculate as much as you can in `prepareUpdate` so that `commitUpdate` can be very fast and straightforward.
155 *
156 * See the meaning of `rootContainer` and `hostContext` in the `createInstance` documentation.
157 */
158 prepareUpdate(
159 instance: Instance,
160 type: Type,
161 oldProps: Props,
162 newProps: Props,
163 rootContainer: Container,
164 hostContext: HostContext,
165 ): UpdatePayload | null;
166
167 /**
168 * Some target platforms support setting an instance's text content without manually creating a text node. For example, in the DOM, you can set `node.textContent` instead of creating a text node and appending it.
169 *
170 * If you return `true` from this method, React will assume that this node's children are text, and will not create nodes for them. It will instead rely on you to have filled that text during `createInstance`. This is a performance optimization. For example, the DOM renderer returns `true` only if `type` is a known text-only parent (like `'textarea'`) or if `props.children` has a `'string'` type. If you return `true`, you will need to implement `resetTextContent` too.
171 *
172 * If you don't want to do anything here, you should return `false`.
173 *
174 * This method happens **in the render phase**. Do not mutate the tree from it.
175 */
176 shouldSetTextContent(type: Type, props: Props): boolean;
177
178 /**
179 * This method lets you return the initial host context from the root of the tree. See `getChildHostContext` for the explanation of host context.
180 *
181 * If you don't intend to use host context, you can return `null`.
182 *
183 * This method happens **in the render phase**. Do not mutate the tree from it.
184 */
185 getRootHostContext(rootContainer: Container): HostContext | null;
186
187 /**
188 * Host context lets you track some information about where you are in the tree so that it's available inside `createInstance` as the `hostContext` parameter. For example, the DOM renderer uses it to track whether it's inside an HTML or an SVG tree, because `createInstance` implementation needs to be different for them.
189 *
190 * If the node of this `type` does not influence the context you want to pass down, you can return `parentHostContext`. Alternatively, you can return any custom object representing the information you want to pass down.
191 *
192 * If you don't want to do anything here, return `parentHostContext`.
193 *
194 * This method happens **in the render phase**. Do not mutate the tree from it.
195 */
196 getChildHostContext(parentHostContext: HostContext, type: Type, rootContainer: Container): HostContext;
197
198 /**
199 * Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But in some cases it might make sense to only expose some part of it.
200 *
201 * If you don't want to do anything here, return `instance`.
202 */
203 getPublicInstance(instance: Instance | TextInstance): PublicInstance;
204
205 /**
206 * This method lets you store some information before React starts making changes to the tree on the screen. For example, the DOM renderer stores the current text selection so that it can later restore it. This method is mirrored by `resetAfterCommit`.
207 *
208 * Even if you don't want to do anything here, you need to return `null` from it.
209 */
210 prepareForCommit(containerInfo: Container): Record<string, any> | null;
211
212 /**
213 * This method is called right after React has performed the tree mutations. You can use it to restore something you've stored in `prepareForCommit` — for example, text selection.
214 *
215 * You can leave it empty.
216 */
217 resetAfterCommit(containerInfo: Container): void;
218
219 /**
220 * This method is called for a container that's used as a portal target. Usually you can leave it empty.
221 */
222 preparePortalMount(containerInfo: Container): void;
223
224 /**
225 * You can proxy this to `setTimeout` or its equivalent in your environment.
226 */
227 scheduleTimeout(fn: (...args: unknown[]) => unknown, delay?: number): TimeoutHandle;
228
229 /**
230 * You can proxy this to `clearTimeout` or its equivalent in your environment.
231 */
232 cancelTimeout(id: TimeoutHandle): void;
233
234 /**
235 * This is a property (not a function) that should be set to something that can never be a valid timeout ID. For example, you can set it to `-1`.
236 */
237 noTimeout: NoTimeout;
238
239 /**
240 * Set this to `true` to indicate that your renderer supports `scheduleMicrotask`. We use microtasks as part of our discrete event implementation in React DOM. If you're not sure if your renderer should support this, you probably should. The option to not implement `scheduleMicrotask` exists so that platforms with more control over user events, like React Native, can choose to use a different mechanism.
241 */
242 supportsMicrotasks?: boolean;
243
244 /**
245 * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.
246 */
247 scheduleMicrotask?(fn: () => unknown): void;
248
249 /**
250 * This is a property (not a function) that should be set to `true` if your renderer is the main one on the page. For example, if you're writing a renderer for the Terminal, it makes sense to set it to `true`, but if your renderer is used *on top of* React DOM or some other existing renderer, set it to `false`.
251 */
252 isPrimaryRenderer: boolean;
253
254 /**
255 * Whether the renderer shouldn't trigger missing `act()` warnings
256 */
257 warnsIfNotActing?: boolean;
258
259 /**
260 * To implement this method, you'll need some constants available on the special `react-reconciler/constants` entry point:
261 *
262 * ```
263 * import {
264 * DiscreteEventPriority,
265 * ContinuousEventPriority,
266 * DefaultEventPriority,
267 * } from 'react-reconciler/constants';
268 *
269 * const HostConfig = {
270 * // ...
271 * getCurrentEventPriority() {
272 * return DefaultEventPriority;
273 * },
274 * // ...
275 * }
276 *
277 * const MyRenderer = Reconciler(HostConfig);
278 * ```
279 *
280 * The constant you return depends on which event, if any, is being handled right now. (In the browser, you can check this using `window.event && window.event.type`).
281 *
282 * - **Discrete events**: If the active event is directly caused by the user (such as mouse and keyboard events) and each event in a sequence is intentional (e.g. click), return DiscreteEventPriority. This tells React that they should interrupt any background work and cannot be batched across time.
283 *
284 * - **Continuous events**: If the active event is directly caused by the user but the user can't distinguish between individual events in a sequence (e.g. mouseover), return ContinuousEventPriority. This tells React they should interrupt any background work but can be batched across time.
285 *
286 * - **Other events / No active event**: In all other cases, return DefaultEventPriority. This tells React that this event is considered background work, and interactive events will be prioritized over it.
287 *
288 * You can consult the `getCurrentEventPriority()` implementation in `ReactDOMHostConfig.js` for a reference implementation.
289 */
290 getCurrentEventPriority(): Lane;
291
292 getInstanceFromNode(node: any): Fiber | null | undefined;
293
294 beforeActiveInstanceBlur(): void;
295
296 afterActiveInstanceBlur(): void;
297
298 prepareScopeUpdate(scopeInstance: any, instance: any): void;
299
300 getInstanceFromScope(scopeInstance: any): null | Instance;
301
302 detachDeletedInstance(node: Instance): void;
303
304 // -------------------
305 // Mutation Methods
306 // (optional)
307 // If you're using React in mutation mode (you probably do), you'll need to implement a few more methods.
308 // -------------------
309
310 /**
311 * This method should mutate the `parentInstance` and add the child to its list of children. For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.
312 *
313 * Although this method currently runs in the commit phase, you still should not mutate any other nodes in it. If you need to do some additional work when a node is definitely connected to the visible tree, look at `commitMount`.
314 */
315 appendChild?(parentInstance: Instance, child: Instance | TextInstance): void;
316
317 /**
318 * Same as `appendChild`, but for when a node is attached to the root container. This is useful if attaching to the root has a slightly different implementation, or if the root container nodes are of a different type than the rest of the tree.
319 */
320 appendChildToContainer?(container: Container, child: Instance | TextInstance): void;
321
322 /**
323 * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list of its children. For example, in the DOM this would translate to a `parentInstance.insertBefore(child, beforeChild)` call.
324 *
325 * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is expected that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts of the tree from it.
326 */
327 insertBefore?(
328 parentInstance: Instance,
329 child: Instance | TextInstance,
330 beforeChild: Instance | TextInstance | SuspenseInstance,
331 ): void;
332
333 /**
334 * Same as `insertBefore`, but for when a node is attached to the root container. This is useful if attaching to the root has a slightly different implementation, or if the root container nodes are of a different type than the rest of the tree.
335 */
336 insertInContainerBefore?(
337 container: Container,
338 child: Instance | TextInstance,
339 beforeChild: Instance | TextInstance | SuspenseInstance,
340 ): void;
341
342 /**
343 * This method should mutate the `parentInstance` to remove the `child` from the list of its children.
344 *
345 * React will only call it for the top-level node that is being removed. It is expected that garbage collection would take care of the whole subtree. You are not expected to traverse the child tree in it.
346 */
347 removeChild?(parentInstance: Instance, child: Instance | TextInstance | SuspenseInstance): void;
348
349 /**
350 * Same as `removeChild`, but for when a node is detached from the root container. This is useful if attaching to the root has a slightly different implementation, or if the root container nodes are of a different type than the rest of the tree.
351 */
352 removeChildFromContainer?(container: Container, child: Instance | TextInstance | SuspenseInstance): void;
353
354 /**
355 * If you returned `true` from `shouldSetTextContent` for the previous props, but returned `false` from `shouldSetTextContent` for the next props, React will call this method so that you can clear the text content you were managing manually. For example, in the DOM you could set `node.textContent = ''`.
356 *
357 * If you never return `true` from `shouldSetTextContent`, you can leave it empty.
358 */
359 resetTextContent?(instance: Instance): void;
360
361 /**
362 * This method should mutate the `textInstance` and update its text content to `nextText`.
363 *
364 * Here, `textInstance` is a node created by `createTextInstance`.
365 */
366 commitTextUpdate?(textInstance: TextInstance, oldText: string, newText: string): void;
367
368 /**
369 * This method is only called if you returned `true` from `finalizeInitialChildren` for this instance.
370 *
371 * It lets you do some additional work after the node is actually attached to the tree on the screen for the first time. For example, the DOM renderer uses it to trigger focus on nodes with the `autoFocus` attribute.
372 *
373 * Note that `commitMount` does not mirror `removeChild` one to one because `removeChild` is only called for the top-level removed node. This is why ideally `commitMount` should not mutate any nodes other than the `instance` itself. For example, if it registers some events on some node above, it will be your responsibility to traverse the tree in `removeChild` and clean them up, which is not ideal.
374 *
375 * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields, be aware that it may change significantly between versions. You're taking on additional maintenance risk by reading from it, and giving up all guarantees if you write something to it.
376 *
377 * If you never return `true` from `finalizeInitialChildren`, you can leave it empty.
378 */
379 commitMount?(instance: Instance, type: Type, props: Props, internalInstanceHandle: OpaqueHandle): void;
380
381 /**
382 * This method should mutate the `instance` according to the set of changes in `updatePayload`. Here, `updatePayload` is the object that you've returned from `prepareUpdate` and has an arbitrary structure that makes sense for your renderer. For example, the DOM renderer returns an update payload like `[prop1, value1, prop2, value2, ...]` from `prepareUpdate`, and that structure gets passed into `commitUpdate`. Ideally, all the diffing and calculation should happen inside `prepareUpdate` so that `commitUpdate` can be fast and straightforward.
383 *
384 * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields, be aware that it may change significantly between versions. You're taking on additional maintenance risk by reading from it, and giving up all guarantees if you write something to it.
385 */
386 commitUpdate?(
387 instance: Instance,
388 updatePayload: UpdatePayload,
389 type: Type,
390 prevProps: Props,
391 nextProps: Props,
392 internalHandle: OpaqueHandle,
393 ): void;
394
395 /**
396 * This method should make the `instance` invisible without removing it from the tree. For example, it can apply visual styling to hide it. It is used by Suspense to hide the tree while the fallback is visible.
397 */
398 hideInstance?(instance: Instance): void;
399
400 /**
401 * Same as `hideInstance`, but for nodes created by `createTextInstance`.
402 */
403 hideTextInstance?(textInstance: TextInstance): void;
404
405 /**
406 * This method should make the `instance` visible, undoing what `hideInstance` did.
407 */
408 unhideInstance?(instance: Instance, props: Props): void;
409
410 /**
411 * Same as `unhideInstance`, but for nodes created by `createTextInstance`.
412 */
413 unhideTextInstance?(textInstance: TextInstance, text: string): void;
414
415 /**
416 * This method should mutate the `container` root node and remove all children from it.
417 */
418 clearContainer?(container: Container): void;
419
420 // -------------------
421 // Persistence Methods
422 // (optional)
423 // If you use the persistent mode instead of the mutation mode, you would still need the "Core Methods". However, instead of the Mutation Methods above you will implement a different set of methods that performs cloning nodes and replacing them at the root level. You can find a list of them in the "Persistence" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js). File an issue if you need help.
424 // -------------------
425 cloneInstance?(
426 instance: Instance,
427 updatePayload: UpdatePayload,
428 type: Type,
429 oldProps: Props,
430 newProps: Props,
431 internalInstanceHandle: OpaqueHandle,
432 keepChildren: boolean,
433 recyclableInstance: null | Instance,
434 ): Instance;
435 createContainerChildSet?(container: Container): ChildSet;
436 appendChildToContainerChildSet?(childSet: ChildSet, child: Instance | TextInstance): void;
437 finalizeContainerChildren?(container: Container, newChildren: ChildSet): void;
438 replaceContainerChildren?(container: Container, newChildren: ChildSet): void;
439 cloneHiddenInstance?(
440 instance: Instance,
441 type: Type,
442 props: Props,
443 internalInstanceHandle: OpaqueHandle,
444 ): Instance;
445 cloneHiddenTextInstance?(instance: Instance, text: Type, internalInstanceHandle: OpaqueHandle): TextInstance;
446
447 // -------------------
448 // Hydration Methods
449 // (optional)
450 // You can optionally implement hydration to "attach" to the existing tree during the initial render instead of creating it from scratch. For example, the DOM renderer uses this to attach to an HTML markup.
451 //
452 // To support hydration, you need to declare `supportsHydration: true` and then implement the methods in the "Hydration" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js). File an issue if you need help.
453 // -------------------
454 supportsHydration: boolean;
455
456 canHydrateInstance?(instance: HydratableInstance, type: Type, props: Props): null | Instance;
457
458 canHydrateTextInstance?(instance: HydratableInstance, text: string): null | TextInstance;
459
460 canHydrateSuspenseInstance?(instance: HydratableInstance): null | SuspenseInstance;
461
462 isSuspenseInstancePending?(instance: SuspenseInstance): boolean;
463
464 isSuspenseInstanceFallback?(instance: SuspenseInstance): boolean;
465
466 registerSuspenseInstanceRetry?(instance: SuspenseInstance, callback: () => void): void;
467
468 getNextHydratableSibling?(instance: HydratableInstance): null | HydratableInstance;
469
470 getFirstHydratableChild?(parentInstance: Container | Instance): null | HydratableInstance;
471
472 hydrateInstance?(
473 instance: Instance,
474 type: Type,
475 props: Props,
476 rootContainerInstance: Container,
477 hostContext: HostContext,
478 internalInstanceHandle: any,
479 ): null | any[];
480
481 hydrateTextInstance?(textInstance: TextInstance, text: string, internalInstanceHandle: any): boolean;
482
483 hydrateSuspenseInstance?(suspenseInstance: SuspenseInstance, internalInstanceHandle: any): void;
484
485 getNextHydratableInstanceAfterSuspenseInstance?(suspenseInstance: SuspenseInstance): null | HydratableInstance;
486
487 // Returns the SuspenseInstance if this node is a direct child of a
488 // SuspenseInstance. I.e. if its previous sibling is a Comment with
489 // SUSPENSE_x_START_DATA. Otherwise, null.
490 getParentSuspenseInstance?(targetInstance: any): null | SuspenseInstance;
491
492 commitHydratedContainer?(container: Container): void;
493
494 commitHydratedSuspenseInstance?(suspenseInstance: SuspenseInstance): void;
495
496 didNotMatchHydratedContainerTextInstance?(
497 parentContainer: Container,
498 textInstance: TextInstance,
499 text: string,
500 ): void;
501
502 didNotMatchHydratedTextInstance?(
503 parentType: Type,
504 parentProps: Props,
505 parentInstance: Instance,
506 textInstance: TextInstance,
507 text: string,
508 ): void;
509
510 didNotHydrateContainerInstance?(parentContainer: Container, instance: HydratableInstance): void;
511
512 didNotHydrateInstance?(
513 parentType: Type,
514 parentProps: Props,
515 parentInstance: Instance,
516 instance: HydratableInstance,
517 ): void;
518
519 didNotFindHydratableContainerInstance?(parentContainer: Container, type: Type, props: Props): void;
520
521 didNotFindHydratableContainerTextInstance?(parentContainer: Container, text: string): void;
522
523 didNotFindHydratableContainerSuspenseInstance?(parentContainer: Container): void;
524
525 didNotFindHydratableInstance?(
526 parentType: Type,
527 parentProps: Props,
528 parentInstance: Instance,
529 type: Type,
530 props: Props,
531 ): void;
532
533 didNotFindHydratableTextInstance?(
534 parentType: Type,
535 parentProps: Props,
536 parentInstance: Instance,
537 text: string,
538 ): void;
539
540 didNotFindHydratableSuspenseInstance?(parentType: Type, parentProps: Props, parentInstance: Instance): void;
541
542 errorHydratingContainer?(parentContainer: Container): void;
543 }
544
545 interface Thenable<T> {
546 then(resolve: () => T, reject?: () => T): T;
547 }
548
549 type RootTag = 0 | 1 | 2;
550
551 type WorkTag =
552 | 0
553 | 1
554 | 2
555 | 3
556 | 4
557 | 5
558 | 6
559 | 7
560 | 8
561 | 9
562 | 10
563 | 11
564 | 12
565 | 13
566 | 14
567 | 15
568 | 16
569 | 17
570 | 18
571 | 19
572 | 20
573 | 21
574 | 22
575 | 23
576 | 24;
577
578 type HookType =
579 | "useState"
580 | "useReducer"
581 | "useContext"
582 | "useRef"
583 | "useEffect"
584 | "useLayoutEffect"
585 | "useCallback"
586 | "useMemo"
587 | "useImperativeHandle"
588 | "useDebugValue"
589 | "useDeferredValue"
590 | "useTransition"
591 | "useMutableSource"
592 | "useOpaqueIdentifier"
593 | "useCacheRefresh";
594
595 interface Source {
596 fileName: string;
597 lineNumber: number;
598 }
599
600 // TODO: Ideally these types would be opaque but that doesn't work well with
601 // our reconciler fork infra, since these leak into non-reconciler packages.
602 type LanePriority = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17;
603
604 type Lanes = number;
605 type Lane = number;
606
607 type Flags = number;
608
609 type TypeOfMode = number;
610
611 interface ReactProvider<T> {
612 $$typeof: symbol | number;
613 type: ReactProviderType<T>;
614 key: null | string;
615 ref: null;
616 props: {
617 value: T;
618 children?: ReactNode;
619 };
620 }
621
622 interface ReactProviderType<T> {
623 $$typeof: symbol | number;
624 _context: ReactContext<T>;
625 }
626
627 interface ReactConsumer<T> {
628 $$typeof: symbol | number;
629 type: ReactContext<T>;
630 key: null | string;
631 ref: null;
632 props: {
633 children: (value: T) => ReactNode;
634 unstable_observedBits?: number;
635 };
636 }
637
638 interface ReactContext<T> {
639 $$typeof: symbol | number;
640 Consumer: ReactContext<T>;
641 Provider: ReactProviderType<T>;
642 _calculateChangedBits: ((a: T, b: T) => number) | null;
643 _currentValue: T;
644 _currentValue2: T;
645 _threadCount: number;
646 // DEV only
647 _currentRenderer?: {
648 [key: string]: any;
649 } | null;
650 _currentRenderer2?: {
651 [key: string]: any;
652 } | null;
653 // This value may be added by application code
654 // to improve DEV tooling display names
655 displayName?: string;
656 }
657
658 interface ReactPortal {
659 $$typeof: symbol | number;
660 key: null | string;
661 containerInfo: any;
662 children: ReactNode;
663 // TODO: figure out the API for cross-renderer implementation.
664 implementation: any;
665 }
666
667 interface RefObject {
668 current: any;
669 }
670
671 interface ContextDependency<T> {
672 context: ReactContext<T>;
673 observedBits: number;
674 next: ContextDependency<unknown> | null;
675 }
676
677 interface Dependencies {
678 lanes: Lanes;
679 firstContext: ContextDependency<unknown> | null;
680 }
681
682 interface Fiber {
683 // These first fields are conceptually members of an Instance. This used to
684 // be split into a separate type and intersected with the other Fiber fields,
685 // but until Flow fixes its intersection bugs, we've merged them into a
686 // single type.
687
688 // An Instance is shared between all versions of a component. We can easily
689 // break this out into a separate object to avoid copying so much to the
690 // alternate versions of the tree. We put this on a single object for now to
691 // minimize the number of objects created during the initial render.
692
693 // Tag identifying the type of fiber.
694 tag: WorkTag;
695
696 // Unique identifier of this child.
697 key: null | string;
698
699 // The value of element.type which is used to preserve the identity during
700 // reconciliation of this child.
701 elementType: any;
702
703 // The resolved function/class/ associated with this fiber.
704 type: any;
705
706 // The local state associated with this fiber.
707 stateNode: any;
708
709 // Conceptual aliases
710 // parent : Instance -> return The parent happens to be the same as the
711 // return fiber since we've merged the fiber and instance.
712
713 // Remaining fields belong to Fiber
714
715 // The Fiber to return to after finishing processing this one.
716 // This is effectively the parent, but there can be multiple parents (two)
717 // so this is only the parent of the thing we're currently processing.
718 // It is conceptually the same as the return address of a stack frame.
719 return: Fiber | null;
720
721 // Singly Linked List Tree Structure.
722 child: Fiber | null;
723 sibling: Fiber | null;
724 index: number;
725
726 // The ref last used to attach this node.
727 // I'll avoid adding an owner field for prod and model that as functions.
728 ref:
729 | null
730 | (((handle: unknown) => void) & {
731 _stringRef?: string | null;
732 })
733 | RefObject;
734
735 // Input is the data coming into process this fiber. Arguments. Props.
736 pendingProps: any; // This type will be more specific once we overload the tag.
737 memoizedProps: any; // The props used to create the output.
738
739 // A queue of state updates and callbacks.
740 updateQueue: unknown;
741
742 // The state used to create the output
743 memoizedState: any;
744
745 // Dependencies (contexts, events) for this fiber, if it has any
746 dependencies: Dependencies | null;
747
748 // Bitfield that describes properties about the fiber and its subtree. E.g.
749 // the ConcurrentMode flag indicates whether the subtree should be async-by-
750 // default. When a fiber is created, it inherits the mode of its
751 // parent. Additional flags can be set at creation time, but after that the
752 // value should remain unchanged throughout the fiber's lifetime, particularly
753 // before its child fibers are created.
754 mode: TypeOfMode;
755
756 // Effect
757 flags: Flags;
758 subtreeFlags: Flags;
759 deletions: Fiber[] | null;
760
761 // Singly linked list fast path to the next fiber with side-effects.
762 nextEffect: Fiber | null;
763
764 // The first and last fiber with side-effect within this subtree. This allows
765 // us to reuse a slice of the linked list when we reuse the work done within
766 // this fiber.
767 firstEffect: Fiber | null;
768 lastEffect: Fiber | null;
769
770 lanes: Lanes;
771 childLanes: Lanes;
772
773 // This is a pooled version of a Fiber. Every fiber that gets updated will
774 // eventually have a pair. There are cases when we can clean up pairs to save
775 // memory if we need to.
776 alternate: Fiber | null;
777
778 // Time spent rendering this Fiber and its descendants for the current update.
779 // This tells us how well the tree makes use of sCU for memoization.
780 // It is reset to 0 each time we render and only updated when we don't bailout.
781 // This field is only set when the enableProfilerTimer flag is enabled.
782 actualDuration?: number;
783
784 // If the Fiber is currently active in the "render" phase,
785 // This marks the time at which the work began.
786 // This field is only set when the enableProfilerTimer flag is enabled.
787 actualStartTime?: number;
788
789 // Duration of the most recent render time for this Fiber.
790 // This value is not updated when we bailout for memoization purposes.
791 // This field is only set when the enableProfilerTimer flag is enabled.
792 selfBaseDuration?: number;
793
794 // Sum of base times for all descendants of this Fiber.
795 // This value bubbles up during the "complete" phase.
796 // This field is only set when the enableProfilerTimer flag is enabled.
797 treeBaseDuration?: number;
798
799 // Conceptual aliases
800 // workInProgress : Fiber -> alternate The alternate used for reuse happens
801 // to be the same as work in progress.
802 // __DEV__ only
803 _debugID?: number;
804 _debugSource?: Source | null;
805 _debugOwner?: Fiber | null;
806 _debugIsCurrentlyTiming?: boolean;
807 _debugNeedsRemount?: boolean;
808
809 // Used to verify that the order of hooks does not change between renders.
810 _debugHookTypes?: HookType[] | null;
811 }
812
813 type FiberRoot = any;
814
815 // Concurrent related struct
816 type MutableSource = any;
817
818 type OpaqueHandle = any;
819 type OpaqueRoot = any;
820
821 // 0 is PROD, 1 is DEV.
822 // Might add PROFILE later.
823 type BundleType = 0 | 1;
824
825 interface DevToolsConfig<Instance, TextInstance, RendererInspectionConfig> {
826 bundleType: BundleType;
827 version: string;
828 rendererPackageName: string;
829 // Note: this actually *does* depend on Fiber internal fields.
830 // Used by "inspect clicked DOM element" in React DevTools.
831 findFiberByHostInstance?: (instance: Instance | TextInstance) => Fiber | null;
832 rendererConfig?: RendererInspectionConfig;
833 }
834
835 interface SuspenseHydrationCallbacks<SuspenseInstance> {
836 onHydrated?: (suspenseInstance: SuspenseInstance) => void;
837 onDeleted?: (suspenseInstance: SuspenseInstance) => void;
838 }
839
840 interface TransitionTracingCallbacks {
841 onTransitionStart?: (transitionName: string, startTime: number) => void;
842 onTransitionProgress?: (
843 transitionName: string,
844 startTime: number,
845 currentTime: number,
846 pending: Array<{ name: null | string }>,
847 ) => void;
848 onTransitionIncomplete?: (
849 transitionName: string,
850 startTime: number,
851 deletions: Array<{
852 type: string;
853 name?: string;
854 newName?: string;
855 endTime: number;
856 }>,
857 ) => void;
858 onTransitionComplete?: (transitionName: string, startTime: number, endTime: number) => void;
859 onMarkerProgress?: (
860 transitionName: string,
861 marker: string,
862 startTime: number,
863 currentTime: number,
864 pending: Array<{ name: null | string }>,
865 ) => void;
866 onMarkerIncomplete?: (
867 transitionName: string,
868 marker: string,
869 startTime: number,
870 deletions: Array<{
871 type: string;
872 name?: string;
873 newName?: string;
874 endTime: number;
875 }>,
876 ) => void;
877 onMarkerComplete?: (transitionName: string, marker: string, startTime: number, endTime: number) => void;
878 }
879
880 interface ComponentSelector {
881 $$typeof: symbol | number;
882 value: React$AbstractComponent<never, unknown>;
883 }
884
885 interface HasPseudoClassSelector {
886 $$typeof: symbol | number;
887 value: Selector[];
888 }
889
890 interface RoleSelector {
891 $$typeof: symbol | number;
892 value: string;
893 }
894
895 interface TextSelector {
896 $$typeof: symbol | number;
897 value: string;
898 }
899
900 interface TestNameSelector {
901 $$typeof: symbol | number;
902 value: string;
903 }
904
905 type Selector = ComponentSelector | HasPseudoClassSelector | RoleSelector | TextSelector | TestNameSelector;
906
907 // TODO can not find React$AbstractComponent def
908 type React$AbstractComponent<Config, Instance = any> = any;
909
910 interface BoundingRect {
911 x: number;
912 y: number;
913 width: number;
914 height: number;
915 }
916
917 type IntersectionObserverOptions = any;
918
919 interface Reconciler<Container, Instance, TextInstance, SuspenseInstance, PublicInstance> {
920 createContainer(
921 containerInfo: Container,
922 tag: RootTag,
923 hydrationCallbacks: null | SuspenseHydrationCallbacks<SuspenseInstance>,
924 isStrictMode: boolean,
925 concurrentUpdatesByDefaultOverride: null | boolean,
926 identifierPrefix: string,
927 onRecoverableError: (error: Error) => void,
928 transitionCallbacks: null | TransitionTracingCallbacks,
929 ): OpaqueRoot;
930
931 createPortal(
932 children: ReactNode,
933 containerInfo: any, // TODO: figure out the API for cross-renderer implementation.
934 implementation: any,
935 key?: string | null,
936 ): ReactPortal;
937
938 registerMutableSourceForHydration(root: FiberRoot, mutableSource: MutableSource): void;
939
940 createComponentSelector(component: React$AbstractComponent<never, unknown>): ComponentSelector;
941
942 createHasPseudoClassSelector(selectors: Selector[]): HasPseudoClassSelector;
943
944 createRoleSelector(role: string): RoleSelector;
945
946 createTextSelector(text: string): TextSelector;
947
948 createTestNameSelector(id: string): TestNameSelector;
949
950 getFindAllNodesFailureDescription(hostRoot: Instance, selectors: Selector[]): string | null;
951
952 findAllNodes(hostRoot: Instance, selectors: Selector[]): Instance[];
953
954 findBoundingRects(hostRoot: Instance, selectors: Selector[]): BoundingRect[];
955
956 focusWithin(hostRoot: Instance, selectors: Selector[]): boolean;
957
958 observeVisibleRects(
959 hostRoot: Instance,
960 selectors: Selector[],
961 callback: (intersections: Array<{ ratio: number; rect: BoundingRect }>) => void,
962 options?: IntersectionObserverOptions,
963 ): { disconnect: () => void };
964
965 createHydrationContainer(
966 initialChildren: ReactNode,
967 callback: (() => void) | null | undefined,
968 containerInfo: Container,
969 tag: RootTag,
970 hydrationCallbacks: null | SuspenseHydrationCallbacks<SuspenseInstance>,
971 isStrictMode: boolean,
972 concurrentUpdatesByDefaultOverride: null | boolean,
973 identifierPrefix: string,
974 onRecoverableError: (error: Error) => void,
975 transitionCallbacks: null | TransitionTracingCallbacks,
976 ): OpaqueRoot;
977
978 updateContainer(
979 element: ReactNode,
980 container: OpaqueRoot,
981 parentComponent?: Component<any, any> | null,
982 callback?: (() => void) | null,
983 ): Lane;
984
985 batchedUpdates<A, R>(fn: (a: A) => R, a: A): R;
986
987 deferredUpdates<A>(fn: () => A): A;
988
989 discreteUpdates<A, B, C, D, R>(fn: (arg0: A, arg1: B, arg2: C, arg3: D) => R, a: A, b: B, c: C, d: D): R;
990
991 flushControlled(fn: () => any): void;
992
993 flushSync(): void;
994 flushSync<R>(fn: () => R): R;
995
996 isAlreadyRendering(): boolean;
997
998 flushPassiveEffects(): boolean;
999
1000 getPublicRootInstance(container: OpaqueRoot): Component<any, any> | PublicInstance | null;
1001
1002 attemptSynchronousHydration(fiber: Fiber): void;
1003
1004 attemptDiscreteHydration(fiber: Fiber): void;
1005
1006 attemptContinuousHydration(fiber: Fiber): void;
1007
1008 attemptHydrationAtCurrentPriority(fiber: Fiber): void;
1009
1010 getCurrentUpdatePriority(): LanePriority;
1011
1012 runWithPriority<T>(priority: LanePriority, fn: () => T): T;
1013
1014 findHostInstance(component: any): PublicInstance | null;
1015
1016 findHostInstanceWithWarning(component: any, methodName: string): PublicInstance | null;
1017
1018 findHostInstanceWithNoPortals(fiber: Fiber): PublicInstance | null;
1019
1020 shouldError(fiber: Fiber): boolean | undefined;
1021
1022 shouldSuspend(fiber: Fiber): boolean;
1023
1024 injectIntoDevTools(devToolsConfig: DevToolsConfig<Instance, TextInstance, any>): boolean;
1025 }
1026}
1027
1028export = ReactReconciler;
1029
\No newline at end of file