MCPcopy
hub / github.com/facebook/react / finishFunctionComponent

Function finishFunctionComponent

packages/react-server/src/ReactFizzServer.js:2571–2628  ·  view source on GitHub ↗
(
  request: Request,
  task: Task,
  keyPath: KeyNode,
  children: ReactNodeList,
  hasId: boolean,
  actionStateCount: number,
  actionStateMatchingIndex: number,
)

Source from the content-addressed store, hash-verified

2569}
2570
2571function finishFunctionComponent(
2572 request: Request,
2573 task: Task,
2574 keyPath: KeyNode,
2575 children: ReactNodeList,
2576 hasId: boolean,
2577 actionStateCount: number,
2578 actionStateMatchingIndex: number,
2579) {
2580 let didEmitActionStateMarkers = false;
2581 if (actionStateCount !== 0 && request.formState !== null) {
2582 // For each useActionState hook, emit a marker that indicates whether we
2583 // rendered using the form state passed at the root. We only emit these
2584 // markers if form state is passed at the root.
2585 const segment = task.blockedSegment;
2586 if (segment === null) {
2587 // Implies we're in reumable mode.
2588 } else {
2589 didEmitActionStateMarkers = true;
2590 const target = segment.chunks;
2591 for (let i = 0; i < actionStateCount; i++) {
2592 if (i === actionStateMatchingIndex) {
2593 pushFormStateMarkerIsMatching(target);
2594 } else {
2595 pushFormStateMarkerIsNotMatching(target);
2596 }
2597 }
2598 }
2599 }
2600
2601 const prevKeyPath = task.keyPath;
2602 task.keyPath = keyPath;
2603 if (hasId) {
2604 // This component materialized an id. We treat this as its own level, with
2605 // a single "child" slot.
2606 const prevTreeContext = task.treeContext;
2607 const totalChildren = 1;
2608 const index = 0;
2609 // Modify the id context. Because we'll need to reset this if something
2610 // suspends or errors, we'll use the non-destructive render path.
2611 task.treeContext = pushTreeContext(prevTreeContext, totalChildren, index);
2612 renderNode(request, task, children, -1);
2613 // Like the other contexts, this does not need to be in a finally block
2614 // because renderNode takes care of unwinding the stack.
2615 task.treeContext = prevTreeContext;
2616 } else if (didEmitActionStateMarkers) {
2617 // If there were useActionState hooks, we must use the non-destructive path
2618 // because this component is not a pure indirection; we emitted markers
2619 // to the stream.
2620 renderNode(request, task, children, -1);
2621 } else {
2622 // We're now successfully past this task, and we haven't modified the
2623 // context stack. We don't have to pop back to the previous task every
2624 // again, so we can use the destructive recursive form.
2625 renderNodeDestructive(request, task, children, -1);
2626 }
2627 task.keyPath = prevKeyPath;
2628}

Callers 2

renderFunctionComponentFunction · 0.85
renderForwardRefFunction · 0.85

Calls 5

pushTreeContextFunction · 0.90
renderNodeFunction · 0.85
renderNodeDestructiveFunction · 0.85

Tested by

no test coverage detected