コード例 #1
0
ファイル: ReactChildFiber.js プロジェクト: 119120119/react
function createSubsequentChild(
  returnFiber : Fiber, 
  existingChild : ?Fiber, 
  previousSibling : Fiber, 
  newChildren, 
  priority : PriorityLevel
) : Fiber {
  if (typeof newChildren !== 'object' || newChildren === null) {
    return previousSibling;
  }

  switch (newChildren.$$typeof) {
    case REACT_ELEMENT_TYPE: {
      const element = (newChildren : ReactElement<any>);
      if (existingChild &&
          element.type === existingChild.type &&
          element.key === existingChild.key) {
        // TODO: This is not sufficient since previous siblings could be new.
        // Will fix reconciliation properly later.
        const clone = ReactFiber.cloneFiber(existingChild, priority);
        clone.pendingProps = element.props;
        clone.child = existingChild.child;
        clone.sibling = null;
        clone.return = returnFiber;
        previousSibling.sibling = clone;
        return clone;
      }
      const child = ReactFiber.createFiberFromElement(element, priority);
      previousSibling.sibling = child;
      child.return = returnFiber;
      return child;
    }

    case REACT_COROUTINE_TYPE: {
      const coroutine = (newChildren : ReactCoroutine);
      const child = ReactFiber.createFiberFromCoroutine(coroutine, priority);
      previousSibling.sibling = child;
      child.return = returnFiber;
      return child;
    }

    case REACT_YIELD_TYPE: {
      const yieldNode = (newChildren : ReactYield);
      const reifiedYield = ReactReifiedYield.createReifiedYield(yieldNode);
      const child = ReactFiber.createFiberFromYield(yieldNode, priority);
      child.output = reifiedYield;
      previousSibling.sibling = child;
      child.return = returnFiber;
      return child;
    }
  }

  if (Array.isArray(newChildren)) {
    let prev : Fiber = previousSibling;
    let existing : ?Fiber = existingChild;
    for (var i = 0; i < newChildren.length; i++) {
      prev = createSubsequentChild(returnFiber, existing, prev, newChildren[i], priority);
      if (prev && existing) {
        // TODO: This is not correct because there could've been more
        // than one sibling consumed but I don't want to return a tuple.
        existing = existing.sibling;
      }
    }
    return prev;
  } else {
    console.log('Unknown child', newChildren);
    return previousSibling;
  }
}
コード例 #2
0
ファイル: ReactChildFiber.js プロジェクト: 119120119/react
function createFirstChild(returnFiber, existingChild, newChildren, priority) {
  if (typeof newChildren !== 'object' || newChildren === null) {
    return null;
  }

  switch (newChildren.$$typeof) {
    case REACT_ELEMENT_TYPE: {
      const element = (newChildren : ReactElement<any>);
      if (existingChild &&
          element.type === existingChild.type &&
          element.key === existingChild.key) {
        // Get the clone of the existing fiber.
        const clone = ReactFiber.cloneFiber(existingChild, priority);
        clone.pendingProps = element.props;
        clone.child = existingChild.child;
        clone.sibling = null;
        clone.return = returnFiber;
        return clone;
      }
      const child = ReactFiber.createFiberFromElement(element, priority);
      child.return = returnFiber;
      return child;
    }

    case REACT_COROUTINE_TYPE: {
      const coroutine = (newChildren : ReactCoroutine);
      const child = ReactFiber.createFiberFromCoroutine(coroutine, priority);
      child.return = returnFiber;
      return child;
    }

    case REACT_YIELD_TYPE: {
      // A yield results in a fragment fiber whose output is the continuation.
      // TODO: When there is only a single child, we can optimize this to avoid
      // the fragment.
      const yieldNode = (newChildren : ReactYield);
      const reifiedYield = ReactReifiedYield.createReifiedYield(yieldNode);
      const child = ReactFiber.createFiberFromYield(yieldNode, priority);
      child.output = reifiedYield;
      child.return = returnFiber;
      return child;
    }
  }

  if (Array.isArray(newChildren)) {
    var first : ?Fiber = null;
    var prev : ?Fiber = null;
    var existing : ?Fiber = existingChild;
    for (var i = 0; i < newChildren.length; i++) {
      if (prev == null) {
        prev = createFirstChild(returnFiber, existing, newChildren[i], priority);
        first = prev;
      } else {
        prev = createSubsequentChild(returnFiber, existing, prev, newChildren[i], priority);
      }
      if (prev && existing) {
        // TODO: This is not correct because there could've been more
        // than one sibling consumed but I don't want to return a tuple.
        existing = existing.sibling;
      }
    }
    return first;
  } else {
    console.log('Unknown child', newChildren);
    return null;
  }
}