We want to hear from you!Take our 2021 Community Survey!

React v17.0 Candidato à lançamento: Sem novas funcionalidades

August 10, 2020 por Dan Abramov and Rachel Nabors

Hoje, estamos publicando o primeiro candidato à lançamento do React 17. Já se passaram dois anos e meio desde o principal lançamento anterior do React, que é muito tempo, mesmo para os nossos padrões! Nesta postagem do blog, descreveremos a função desta versão principal, quais mudanças você pode esperar dela e como você pode experimentar esta versão.

Sem novas funcionalidades

A versão React 17 é incomum porque não adiciona nenhum novo recurso voltado para o desenvolvedor. Em vez disso, esta versão está focada principalmente em tornar mais fácil atualizar o próprio React.

Estamos trabalhando ativamente nos novos recursos do React, mas eles não fazem parte desta versão. O lançamento do React 17 é uma parte fundamental de nossa estratégia para implementá-los sem deixar ninguém para trás.

Em particular, o React 17 é uma versão “passo a passo” que torna mais seguro incorporar uma árvore gerenciada por uma versão do React dentro de uma árvore gerenciada por uma versão diferente do React.

Atualizações Graduais

Nos últimos sete anos, as atualizações do React têm sido “tudo ou nada”. Ou você permanece com uma versão antiga ou atualiza todo o seu aplicativo para uma nova versão. Não havia meio-termo.

Isso funcionou até agora, mas estamos atingindo os limites da estratégia de atualização “tudo ou nada”. Algumas mudanças de API, por exemplo, descontinuar a legada API de contexto, são impossíveis de fazer de forma automatizada. Mesmo que a maioria dos aplicativos escritos hoje nunca os use, ainda oferecemos suporte para eles no React. Temos que escolher entre suportá-los no React indefinidamente ou deixar alguns aplicativos para trás em uma versão antiga do React. Ambas as opções não são boas.

Portanto, queríamos oferecer outra opção.

React 17 permite atualizações graduais do React. Quando você atualiza do React 15 para o 16 (ou, em breve, do React 16 para o 17), normalmente atualiza todo o seu aplicativo de uma vez. Isso funciona bem para muitos aplicativos. Mas pode ser cada vez mais desafiador se a base de código foi escrita há mais de alguns anos e não é mantida ativamente. E embora seja possível usar duas versões do React na mesma página, até o React 17 isso era frágil e causava problemas com eventos.

Estamos corrigindo muitos desses problemas com o React 17. Isso significa que quando o React 18 e as próximas versões futuras forem lançadas, você terá mais opções. A primeira opção será atualizar todo o seu aplicativo de uma vez, como você pode ter feito antes. Mas você também terá a opção de atualizar seu aplicativo peça por peça. Por exemplo, você pode decidir migrar a maior parte do seu aplicativo para o React 18, mas manter algumas caixas de diálogo lazy-loaded ou um sub-rota no React 17.

Isso não significa que você precise fazer atualizações graduais. Para a maioria dos aplicativos, atualizar tudo de uma vez ainda é a melhor solução. Carregar duas versões do React — mesmo se uma delas for carregada lentamente sob demanda — ainda não é o ideal. No entanto, para aplicativos maiores que não são mantidos ativamente, pode fazer sentido considerar essa opção, e o React 17 permite que esses aplicativos não sejam deixados para trás.

Para permitir atualizações graduais, precisamos fazer algumas mudanças no sistema de eventos do React. O React 17 é um grande lançamento porque essas alterações são potencialmente prejudiciais. Na prática, só tivemos que mudar menos de vinte componentes de mais de 100.000, então esperamos que a maioria dos aplicativos possa atualizar para o React 17 sem muitos problemas. Conte-nos se você tiver problemas.

Demonstração das atualizações graduais

Preparamos um repositório de exemplo demonstrando como carregar lentamente uma versão mais antiga do React, se necessário. Esta demonstração usa Create React App, mas deve ser possível seguir uma abordagem semelhante com qualquer outra ferramenta. Aceitamos pull requests com demonstrações usando outras ferramentas.

Nota

Adiamos outras mudanças até depois do React 17. O objetivo desta versão é permitir atualizações graduais. Se atualizar para React 17 fosse muito difícil, isso iria contra o seu propósito.

Alterações na delegação de eventos

Tecnicamente, sempre foi possível aninhar aplicativos desenvolvidos com diferentes versões do React. No entanto, era bastante frágil por causa de como o sistema de eventos React funcionava.

Nos componentes React, você geralmente escreve manipuladores de eventos (event handler) inline:

<button onClick={handleClick}>

O DOM vanilla equivalente a este código é semelhante à:

myButton.addEventListener('click', handleClick);

No entanto, para a maioria dos eventos, o React não os anexa aos nós DOM nos quais você os declara. Em vez disso, o React anexa um manipulador por tipo de evento diretamente no nó document. Isso é chamado de delegação de evento. Além de seus benefícios de desempenho em grandes árvores de aplicativos, também torna mais fácil adicionar novos recursos como eventos de repetição.

O React faz a delegação de eventos automaticamente desde seu primeiro lançamento. Quando um evento DOM é disparado no documento, o React descobre qual componente deve ser chamado e, em seguida, o evento React “propaga” para cima através de seus componentes. Mas, nos bastidores, o evento nativo já atingiu o nível documento, onde o React instala seus manipuladores de eventos.

No entanto, esse é um problema para atualizações graduais.

Se você tiver várias versões do React na página, todas elas registram manipulador de eventos (event handler) na parte superior. Isso quebra e.stopPropagation(): se uma árvore aninhada parou a propagação de um evento, a árvore externa ainda o receberia. Isso tornou difícil aninhar diferentes versões do React. Essa preocupação não é hipotética — por exemplo, o editor Atom encontrou isso quatro anos atrás.

É por isso que estamos mudando a forma como o React anexa eventos ao DOM nos bastidores.

No React 17, o React não anexará mais manipuladores de eventos no nível do documento. Em vez disso, ele os anexará ao contêiner DOM raiz no qual sua árvore do React é renderizada:

const rootNode = document.getElementById('root');
ReactDOM.render(<App />, rootNode);

No React 16 e anteriores, o React faria document.addEventListener() para a maioria dos eventos. O React 17 chamará rootNode.addEventListener() por debaixo dos panos.

Um diagrama mostrando como o React 17 anexa eventos às raízes em vez de anexar ao documento

Graças a essa mudança, agora é mais seguro incorporar uma árvore do React gerenciada por uma versão dentro de uma árvore gerenciada por uma versão diferente do React. Observe que para que isso funcione, ambas as versões precisam ser 17 ou superior, por isso atualizar para React 17 é importante. De certa forma, o React 17 é um lançamento “trampolim” que torna as próximas atualizações graduais viáveis.

Essa mudança também torna mais fácil incorporar o React em aplicativos desenvolvidos com outras tecnologias. Por exemplo, se o “shell” externo de seu aplicativo for escrito em jQuery, mas o código mais recente dentro dele for escrito com React, e.stopPropagation() dentro do código React agora evitará que ele alcance o código jQuery — como você esperaria. Isso também funciona na outra direção. Se você não gosta mais de React e deseja reescrever seu aplicativo — por exemplo, em jQuery — você pode começar a converter o shell externo de React para jQuery sem interromper a propagação do evento.

Confirmamos que vários problemas relatados ao longo dos anos em nosso rastreador de problemas relacionadas à integração do React com o código não React foram corrigidas pelo novo comportamento.

Nota

Você deve estar se perguntando se isso quebra o Portals fora do contêiner raiz. A resposta é que o React também ouve eventos nos contêineres do portal, portanto, isso não é um problema.

Corrigindo potenciais problemas

Como acontece com qualquer alteração importante, é provável que algum código precise ser ajustado. No Facebook, tivemos que ajustar cerca de 10 módulos no total (de muitos milhares) para trabalhar com essa mudança.

Por exemplo, se você adicionar manualmente os DOM listners com document.addEventListener(...), você pode esperar que eles capturem todos os eventos React. No React 16 e anteriores, mesmo se você chamar e.stopPropagation() em um manipulador de eventos (event handler) do React, seus listners document personalizados ainda os receberão porque o evento nativo está no nível do documento. Com React 17, a propagação iria parar (conforme solicitado!), Então seus manipuladores de document não disparariam:

document.addEventListener('click', function() {
  // Este manipulador personalizado não receberá mais cliques
  // dos componentes React que chamaram e.stopPropagation()
});

Você pode corrigir um código como esse convertendo seu listener para usar a fase de captura. Para fazer isso, você pode passar { capture: true } como o terceiro argumento para document.addEventListener:

document.addEventListener('click', function() {
  // Agora este event handlers usa a fase de captura
  // então ele recebe *todas* os eventos de clique abaixo!
}, { capture: true });

Observe como essa estratégia é mais resiliente no geral — por exemplo, ela provavelmente corrigirá bugs existentes em seu código que acontecem quando e.stopPropagation() é chamado fora de um manipulador de eventos (event handler) React. Em outras palavras, a propagação do evento no React 17 funciona mais próxima do DOM regular .

Outras alterações significativas

Mantivemos as alterações significativas no React 17 ao mínimo. Por exemplo, ele não remove nenhum dos métodos que foram descontinuados nas versões anteriores. No entanto, inclui algumas outras alterações importantes que têm sido relativamente seguras em nossa experiência. No total, tivemos que ajustar menos de 20 de mais de 100.000 nossos componentes por causa deles.

Alinhando com navegadores

Fizemos algumas alterações menores relacionadas ao sistema de eventos:

  • O evento onScroll não propaga mais a fim de previnir algumas confusões comuns.
  • Os eventos React onFocus e onBlur passaram a usar os eventos nativos focusin efocusout por debaixo dos panos, que se aproximam mais do comportamento existente do React e às vezes fornecem informações extras.
  • Os eventos de fase de captura (por exemplo, onClickCapture) agora usam ouvintes de fase de captura do navegador real.

Essas mudanças alinham o React mais de perto com o comportamento do navegador e melhoram a interoperabilidade.

Nota

Embora o React 17 tenha mudado de focus parafocusin por debaixo dos panos para o evento onFocus, note que isso não afetou o comportamento de propagação. No React, o evento onFocus sempre propagava e continua a ocorrer no React 17 porque geralmente é um padrão mais útil. Consulte este sandbox para as diferentes verificações que você pode adicionar para diferentes casos de uso específicos.

Sem pool de eventos

O React 17 remove a otimização de pooling de eventos do React. Ele não melhora o desempenho em navegadores modernos e confunde até mesmo usuários experientes do React:

function handleChange(e) {
  setData(data => ({
    ...data,
    // Isso trava no React 16 e anteriores:
    text: e.target.value
  }));
}

Isso ocorre porque o React reutilizou os objetos de evento entre diferentes eventos para desempenho em navegadores antigos e definiu todos os campos de evento como null entre eles. Com o React 16 e anteriores, você deve chamar e.persist() para usar o evento apropriadamente ou ler a propriedade que você precisa anteriormente.

No React 17, este código funciona conforme o esperado. A antiga otimização do pool de eventos foi totalmente removida, para que você possa ler os campos do evento sempre que precisar.

Esta é uma mudança de comportamento, e é por isso que a estamos marcando como falha, mas na prática não vimos nada quebrar no Facebook. (Talvez até tenha corrigido alguns bugs!) Observe que e.persist() ainda está disponível no objeto de evento React, mas agora não faz nada.

Tempo de limpeza do Effect

Estamos tornando o tempo da função de limpeza useEffect mais consistente.

useEffect (() => {
  // Este é o próprio Effect.
  return () => {    // Esta é sua limpeza.  };});

A maioria dos efeitos não precisa atrasar as atualizações da tela, portanto, o React os executa de forma assíncrona logo após a atualização ser refletida na tela. (Para os raros casos em que você precisa de um efeito para bloquear a pintura, por exemplo, para medir e posicionar uma tooltip, prefira useLayoutEffect.)

No entanto, quando um componente é desmontado, as funções de limpeza de efeito usadas para serem executadas de maneira síncrona (semelhante a componentWillUnmount sendo síncrono em classes). Descobrimos que isso não é ideal para aplicativos maiores porque retarda as transições de telas grandes (por exemplo, alternar entre guias).

No React 17, a função de limpeza de efeito sempre é executada de forma assíncrona — por exemplo, se o componente está desmontado, a limpeza é executada após a tela ter sido atualizada.

Isso reflete como os próprios efeitos funcionam mais de perto. Nos raros casos em que você pode querer confiar na execução síncrona, você pode alternar para useLayoutEffect.

Nota

Você deve estar se perguntando se isso significa que agora você não conseguirá corrigir avisos sobre setState em componentes não montados. Não se preocupe — o React verifica especificamente este caso e não dispara avisos de setState no curto espaço entre a desmontagem e a limpeza.Portanto, as solicitações ou intervalos de cancelamento de código quase sempre podem permanecer os mesmos.

Além disso, o React 17 sempre executará todas as funções de limpeza de efeitos (para todos os componentes) antes de executar quaisquer novos efeitos. O React 16 só garantiu essa ordem para efeitos dentro de um componente.

Problemas potenciais

Nós vimos apenas alguns componentes quebrarem com essa mudança, embora as bibliotecas reutilizáveis ​​possam precisar testá-lo mais completamente. Um exemplo de código problemático pode ser assim:

useEffect(() => {
  someRef.current.someSetupMethod();
  return () => {
    someRef.current.someCleanupMethod();
  };
});

O problema é que someRef.current é mutável, portanto, no momento em que a função de limpeza é executada, pode ter sido definido como null. A solução é capturar quaisquer valores mutáveis ​​dentro do efeito:

useEffect(() => {
  const instance = someRef.current;
  instance.someSetupMethod();
  return () => {
    instance.someCleanupMethod();
  };
});

Não esperamos que este seja um problema comum porque nossa regra de lint eslint-plugin-react-hooks /haustive-deps (certifique-se de usá-lo!) sempre alertamos sobre isso.

Erros consistentes para retornar indefinido

No React 16 e anteriores, retornar undefined sempre foi um erro:

function Button() {
  return; // Erro: nada foi retornado da renderização
}

Isso ocorre em parte porque é fácil retornar undefined involuntariamente:

function Button() {
  // Esquecemos de escrever return, então este componente retorna indefinido.
  // React mostra isso como um erro em vez de ignorá-lo.
  <button />;
}

Anteriormente, o React fazia isso apenas para componentes de classe e função, mas não verificava os valores de retorno dos componentes forwardRef e memo. Isso ocorreu devido a um erro de codificação.

No React 17, o comportamento dos componentes forwardRef e memo é consistente com funções regulares e componentes de classe. Retornar undefined deles é um erro.

let Button = forwardRef(() => {
  // Esquecemos de escrever return, então este componente retorna indefinido.
  // React 17 mostra isso como um erro em vez de ignorá-lo.
  <button />;
});

let Button = memo(() => {
  // Esquecemos de escrever return, então este componente retorna indefinido.
  // React 17 mostra isso como um erro em vez de ignorá-lo.
  <button />;
});

Para os casos em que você não deseja renderizar nada intencionalmente, retorne null.

Pilhas de componentes nativos

Quando você lança um erro no navegador, o navegador fornece um rastreamento de pilha com nomes de função JavaScript e seus locais. No entanto, as pilhas de JavaScript geralmente não são suficientes para diagnosticar um problema porque a hierarquia da árvore React pode ser tão importante. Você quer saber não apenas que um Button gerou um erro, mas onde na árvore React esse Button está.

Para resolver isso, o React 16 começou a imprimir “pilhas de componentes” quando você tinha um erro. Ainda assim, eles costumavam ser inferiores às pilhas nativas de JavaScript. Em particular, eles não podiam ser clicados no console porque o React não sabia onde a função foi declarada no código-fonte. Além disso, eles eram praticamente inúteis na produção. Ao contrário das pilhas JavaScript reduzidas regulares, que podem ser restauradas automaticamente aos nomes das funções originais com um mapa de origem, com as pilhas de componentes React você tinha que escolher entre as pilhas de produção e o tamanho do pacote.

No React 17, as pilhas de componentes são geradas usando um mecanismo diferente que as une a partir das pilhas JavaScript nativas regulares. Isso permite que você obtenha os rastreamentos de pilha do componente React totalmente simbolizados em um ambiente de produção.

A maneira como o React implementa isso é um tanto heterodoxa. Atualmente, os navegadores não fornecem uma maneira de obter o quadro de pilha de uma função (arquivo de origem e localização). Portanto, quando o React detecta um erro, ele agora reconstrói sua pilha de componentes lançando (e capturando) um erro temporário de dentro de cada um dos componentes acima, quando possível. Isso adiciona uma pequena penalidade de desempenho para travamentos, mas só acontece uma vez por tipo de componente.

Se estiver curioso, você pode ler mais detalhes neste pull request, mas na maior parte, este mecanismo exato não deve afetar seu código. De sua perspectiva, o novo recurso é que as pilhas de componentes agora são clicáveis ​​(porque contam com os frames de pilha do navegador nativo) e que você pode decodificá-los em produção como faria com erros regulares de JavaScript.

A parte que constitui uma alteração significativa é que, para que isso funcione, o React executa novamente partes de algumas das funções do React e dos construtores da classe React acima na pilha depois que um erro é capturado. Uma vez que funções de renderização e construtores de classe não devem ter efeitos colaterais (o que também é importante para a renderização de servidor), isso não deve representar nenhum problema prático.

Removendo exportações privadas

Por fim, a última mudança importante notável é que removemos alguns componentes internos do React que foram previamente expostos a outros projetos. Em particular, React Native for Web costumava depender de alguns componentes internos do sistema de eventos, mas essa dependência era frágil e costumava quebrar.

No React 17, essas exportações privadas foram removidas. Pelo que sabemos, React Native for Web foi o único projeto que os utilizou, e eles já concluíram uma migração para uma abordagem diferente que não depende dessas exportações privadas.

Isso significa que as versões anteriores do React Native for Web não serão compatíveis com o React 17, mas as versões mais recentes funcionarão com ele. Na prática, isso não muda muito porque o React Native for Web teve que lançar novas versões para se adaptar às mudanças internas do React.

Além disso, removemos os métodos auxiliares ReactTestUtils.SimulateNative. Eles nunca foram documentados, não cumprem exatamente o que seus nomes indicam e não funcionam com as alterações que fizemos no sistema de eventos. Se você deseja uma maneira conveniente de disparar eventos nativos do navegador em testes, verifique a Biblioteca de testes do React.

Instalação

Incentivamos você a experimentar o React 17.0 Release Candidate em breve e levantar quaisquer problemas para os problemas que você pode encontrar na migração. Lembre-se de que um candidato a lançamento tem mais probabilidade de conter bugs do que um lançamento estável, portanto, não o implante na produção ainda.

Para instalar o React 17 RC com npm, execute:

npm install react@17.0.0-rc.3 react-dom@17.0.0-rc.3

Para instalar o React 17 RC com Yarn, execute:

yarn add react@17.0.0-rc.3 react-dom@17.0.0-rc.3

Também fornecemos compilações UMD do React por meio de um CDN:

<script crossorigin src="https://unpkg.com/react@17.0.0-rc.3/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17.0.0-rc.3/umd/react-dom.production.min.js"></script>

Consulte a documentação para instruções de instalação detalhadas.

Changelog

React

React DOM

  • Delegar eventos para raízes ao invés de document. (@trueadm em #18195 e outros)
  • Limpe todos os efeitos antes de executar os próximos efeitos. (@bvaughn em #17947)
  • Execute as funções de limpeza useEffect de forma assíncrona. (@bvaughn em #17925)
  • Use o navegador focusin e focusout para onFocus e onBlur. (@trueadm em #19186)
  • Faça com que todos os eventos Capture usem a fase de captura do navegador. (@trueadm em #19221)
  • Não emule o propagação do evento onScroll. (@gaearon em #19464)
  • Lance se o componente forwardRef ou memo retornar undefined. (@gaearon em #19550)
  • Remova o pool de eventos. (@trueadm em #18969)
  • Pare de expor detalhes internos que não serão necessários para o React Native Web. (@necolas em #18483)
  • Anexe todos os event listeners conhecidos quando o root for montado. (@gaearon em #19659)
  • Desative o console na segunda passagem de renderização do modo DEV de renderização dupla. (@sebmarkbage em #18547)
  • Descontinue a API ReactTestUtils.SimulateNative não documentada e confusa. (@gaearon em #13407)
  • Renomeie os nomes dos campos privados usados nos internos. (@gaearon em #18377)
  • Não chame a API User Timing no desenvolvimento. (@gaearon em #18417)
  • Desative o console durante a renderização repetida no modo estrito. (@sebmarkbage em #18547)
  • No Modo Estrito, os componentes de renderização dupla sem Hooks também. (@eps1lon em #18430)
  • Permitir chamar ReactDOM.flushSync durante os métodos de ciclo de vida (mas avisar). (@sebmarkbage em #18759)
  • Adicione a propriedade code aos objetos de evento do teclado. (@bl00mber em #18287)
  • Adicione a propriedade disableRemotePlayback para os elementos video. (@tombrowndev em #18619)
  • Adicione a propriedade enterKeyHint para elementos input. (@eps1lon em #18634)
  • Avisar quando nenhum valor é fornecido para <Context.Provider>. (@charlie1404 em #19054)
  • Avisa quando os componentes memo ou forwardRef retornam undefined. (@bvaughn em #19550)
  • Melhore a mensagem de erro para atualizações inválidas. (@JoviDeCroock em #18316)
  • Exclua forwardRef e memo dos frames da pilha. (@sebmarkbage em #18559)
  • Melhore a mensagem de erro ao alternar entre entradas controladas e não controladas. (@vcarl em #17070)
  • Mantenha onTouchStart, onTouchMove e onWheel passivos. (@gaearon em #19654)
  • Corrigir setState pendurado em desenvolvimento dentro de um iframe fechado. (@gaearon em #19220)
  • Corrigir o resgate de renderização para componentes lazy com defaultProps. (@jddxf em #18539)
  • Corrigir um aviso de falso positivo quando hazouslySetInnerHTML é undefined. (@eps1lon em #18676)
  • Corrigir os utilitários de teste com implementação require não padrão. (@just-boris em #18632)
  • Corrigir onBeforeInput relatando um event.type incorreto. (@eps1lon em #19561)
  • Corrigir o event.relatedTarget relatado como undefined no Firefox. (@claytercek em #19607
  • Corrigir “erro não especificado” no IE11. (@hemakshis em #19664)
  • Corrigir a renderização em uma root shadow. (@ Jack-Works em #15894)
  • Corrigir polyfill movementX / Y com eventos de captura. (@gaearon em #19672)
  • Use a delegação para eventos onSubmit e onReset. (@gaearon em #19333)
  • Melhore o uso de memória. (@trueadm em #18970)

Servidor React DOM

  • Torne o comportamento useCallback consistente com useMemo para o renderizador do servidor. (@alexmckenley em #18783)
  • Fix state leaking when a function component throws. (@pmaccart em #19212)

Teste Renderização React

Modo simultâneo (Experimental)

  • Renovar as heurísticas de lote de prioridade. (@acdlite em #18796)
  • Adicione o prefixo unstable_ antes das APIs experimentais. (@acdlite em #18825)
  • Remova unstable_discreteUpdates e unstable_flushDiscreteUpdates. (@trueadm em #18825)
  • Remova o argumento timeoutMs. (@acdlite em #19703)
  • Desabilite <div hidden /> pré-renderizando em favor de uma API futura diferente. (@acdlite em #18917)
  • Adicione unstable_expectedLoadTime no Suspense para a árvores do CPU-bound. (@acdlite em #19936)
  • Adicione um Hook experimental unstable_useOpaqueIdentifier. (@lunaruan em #17322)
  • Adicione uma API experimental unstable_startTransition. (@rickhanlonii em #19696)
  • Usar act em o renderizador de teste não libera mais os fallbacks do Suspense. (@acdlite em #18596)
  • Use o tempo limite de renderização global para CPU Suspense. (@sebmarkbage em #19643)
  • Limpe o conteúdo raiz existente antes de montar. (@bvaughn em #18730)
  • Corrija um bug com limites de erro. (@acdlite em #18265)
  • Corrigir um bug que causava atualizações perdidas em uma árvore suspensa. (@acdlite em #18384 e #18457)
  • Corrigir um bug que causava a queda das atualizações da fase de renderização. (@acdlite em #18537)
  • Corrigir um bug em SuspenseList. (@sebmarkbage em #18412)
  • Corrigido um bug que fazia com que o recurso Suspense fosse exibido muito cedo. (@acdlite em #18411)
  • Corrigir um bug com componentes de classe dentro de SuspenseList. (@sebmarkbage em #18448)
  • Corrigir um bug com entradas que podem fazer com que as atualizações sejam descartadas. (@jddxf em #18515 e @acdlite em #18535)
  • Corrigir um bug que fazia o fallback do Suspense travar. (@acdlite em #18663)
  • Não corte a cauda de um SuspenseList se estiver hidratando. (@sebmarkbage em #18854)
  • Corrigir um bug em useMutableSource que pode acontecer quandogetSnapshot muda. (@bvaughn em #18297)
  • Corrigido um bug de tearing em useMutableSource. (@bvaughn em #18912)
  • Avisa se estiver chamando setState fora da renderização, mas antes do commit. (@sebmarkbage em #18838)
Esta página é útil?Edite esta página