UNPKG

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