( request: Request, task: Task, node: ReactNodeList, childIndex: number, )
| 4129 | // This is a non-destructive form of rendering a node. If it suspends it spawns |
| 4130 | // a new task and restores the context of this task to what it was before. |
| 4131 | function renderNode( |
| 4132 | request: Request, |
| 4133 | task: Task, |
| 4134 | node: ReactNodeList, |
| 4135 | childIndex: number, |
| 4136 | ): void { |
| 4137 | // Snapshot the current context in case something throws to interrupt the |
| 4138 | // process. |
| 4139 | const previousFormatContext = task.formatContext; |
| 4140 | const previousLegacyContext = !disableLegacyContext |
| 4141 | ? task.legacyContext |
| 4142 | : emptyContextObject; |
| 4143 | const previousContext = task.context; |
| 4144 | const previousKeyPath = task.keyPath; |
| 4145 | const previousTreeContext = task.treeContext; |
| 4146 | const previousComponentStack = task.componentStack; |
| 4147 | const previousDebugTask = __DEV__ ? task.debugTask : null; |
| 4148 | let x; |
| 4149 | // Store how much we've pushed at this point so we can reset it in case something |
| 4150 | // suspended partially through writing something. |
| 4151 | const segment = task.blockedSegment; |
| 4152 | if (segment === null) { |
| 4153 | // Replay |
| 4154 | task = ((task: any): ReplayTask); // Refined |
| 4155 | const previousReplaySet: ReplaySet = task.replay; |
| 4156 | try { |
| 4157 | return renderNodeDestructive(request, task, node, childIndex); |
| 4158 | } catch (thrownValue) { |
| 4159 | resetHooksState(); |
| 4160 | |
| 4161 | x = |
| 4162 | thrownValue === SuspenseException |
| 4163 | ? // This is a special type of exception used for Suspense. For historical |
| 4164 | // reasons, the rest of the Suspense implementation expects the thrown |
| 4165 | // value to be a thenable, because before `use` existed that was the |
| 4166 | // (unstable) API for suspending. This implementation detail can change |
| 4167 | // later, once we deprecate the old API in favor of `use`. |
| 4168 | getSuspendedThenable() |
| 4169 | : thrownValue; |
| 4170 | |
| 4171 | if (request.status === ABORTING) { |
| 4172 | // We are aborting so we can just bubble up to the task by falling through |
| 4173 | } else if (typeof x === 'object' && x !== null) { |
| 4174 | // $FlowFixMe[method-unbinding] |
| 4175 | if (typeof x.then === 'function') { |
| 4176 | const wakeable: Wakeable = (x: any); |
| 4177 | const thenableState = |
| 4178 | thrownValue === SuspenseException |
| 4179 | ? getThenableStateAfterSuspending() |
| 4180 | : null; |
| 4181 | const newTask = spawnNewSuspendedReplayTask( |
| 4182 | request, |
| 4183 | // $FlowFixMe: Refined. |
| 4184 | task, |
| 4185 | thenableState, |
| 4186 | ); |
| 4187 | const ping = newTask.ping; |
| 4188 | wakeable.then(ping, ping); |
no test coverage detected