Embora seja tecnicamente possível, o Suspense não se destina atualmente como uma maneira de começar a buscar dados quando um componente é renderizado. Em vez disso, permite que os componentes expressem que estão “aguardando” os dados que já estão sendo buscados. Criando Excelentes Experiências de Usuário com o Modo de Concorrência e Suspensedescreve por que isso é importante e como implementar esse padrão na prática.
A menos que você tenha uma solução que ajude a evitar cascatas, sugerimos que você prefira APIs que favorecem ou reforçam a busca antes da renderização. Para um exemplo concreto, você pode ver como API de Relay Suspense impõe o pré-carregamento. Nossas mensagens sobre isso não foram muito consistentes no passado. O Suspense para Busca de Dados ainda é experimental, portanto, você pode esperar que nossas recomendações mudem com o tempo, à medida que aprendemos mais sobre o uso em produção e entendemos melhor o espaço do problema.
Poderíamos introduzir o Suspense sem mencionar as abordagens populares de busca de dados. No entanto, isso torna mais difícil ver quais problemas o Suspense resolve, por que vale a pena resolvê-los e como o Suspense é diferente das soluções existentes.
Busca-na-renderização (por exemplo, fetch em useEffect): Comece a renderizar componentes. Cada um desses componentes pode acionar a busca de dados em seus efeitos e métodos de ciclo de vida. Essa abordagem geralmente leva a “cascatas”.
Busca-Então-Renderiza (por exemplo, Relay sem Suspense): Comece a buscar todos os dados para a próxima tela o mais cedo possível. Quando os dados estiverem prontos, renderize a nova tela. Não podemos fazer nada até que os dados cheguem.
Renderização-conforme-você-busca (por exemplo, Relay com Suspense): Comece a buscar todos os dados necessários para a próxima tela o mais cedo possível e comece a renderizar a nova tela imediatamente — antes de recebermos uma resposta da rede. À medida que os dados entram, o React tenta renderizar novamente os componentes que ainda precisam dos dados até que estejam prontos.
Isso é um pouco simplificado e, na prática, as soluções tendem a usar uma mistura de diferentes abordagens. Ainda assim, vamos analisá-los isoladamente para contrastar melhor seus prós e contras.
Chamamos essa abordagem de “busca-na-renderização” porque ela não começa a buscar até que o componente seja renderizado na tela. Isso leva a um problema conhecido como “cascata”.
Se a busca de detalhes do usuário demorar três segundos, começaremos a buscar as postagens após três segundos! Isso é uma “cascata”: uma sequência não intencional que deveria ter sido paralelizada.
Cascatas são comuns no código que busca dados na renderização. É possível resolver, mas à medida que o produto cresce, muitas pessoas preferem usar uma solução que proteja contra esse problema.
As bibliotecas podem impedir cascatas, oferecendo uma maneira mais centralizada de buscar dados. Por exemplo, o Relay resolve esse problema movendo as informações sobre os dados que um componente precisa para analisar estaticamente fragments, que mais tarde são compostos em uma única consulta.
Nesta página, não assumimos o conhecimento de Relay, portanto não o usaremos neste exemplo. Em vez disso, escreveremos algo semelhante manualmente combinando nossos métodos de busca de dados:
Resolvemos a “cascata” de rede anterior, mas acidentalmente introduzimos uma diferente. Esperamos que todos os dados retornem com Promise.all() dentro de fetchProfileData, portanto, agora não podemos renderizar os detalhes do perfil até que as postagens também sejam buscadas. Temos que esperar pelos dois.
Obviamente, isso é possível de ser corrigido neste exemplo em particular. Podemos remover a chamada Promise.all() e aguardar as duas Promises separadamente. No entanto, essa abordagem fica progressivamente mais difícil à medida que a complexidade da nossa árvore de dados e componentes aumenta. É difícil escrever componentes confiáveis quando partes arbitrárias da árvore de dados podem estar ausentes ou obsoletas. Portanto, buscar todos os dados para a nova tela e depois renderizar é frequentemente uma opção mais prática.
Com o Suspense, ainda começamos a buscar primeiro, mas nós invertemos de posição os dois últimos passos: