Gosto da abordagem, ela demonstra como o React abraça a composição, não se restringindo à componentes de apresentação. Componentes como QueueComponents implementam a lógica para manipular a renderização.

É possível simplificar o JSX para algo parecido com:

function App() {
  return (
    <QueueComponents>
      <Modal1 />
      <Modal2 />
    </QueueComponents>
  );
}

Perceba que children já é uma coleção de ReactElement, logo QueueComponents pode tirar vantagem disso:

type Props = {
  children: ReactElement[];
};

function QueueComponents({ children }: Props) {
  const [queue, setQueue] = useState<ReactElement[]>(children);
  const [current, setCurrent] = useState<ReactElement | null>(
    children?.[0] ?? null
  );

  function processQueue() {
    const newQueue = queue.slice(1);
    setQueue(newQueue);
    setCurrent(newQueue[0] ?? null);
  }

  if (!current) return null;

  return cloneElement(current, { processQueue });
}

Vale mencionar React.Children.toArray(children) tende a ser melhor opção para o caso de uma manipulação mais complexa de children

Para mais informações sobre a propriedade children:

Muito bom! @willieoliveira