React v17.0 Candidato à lançamento: Sem novas funcionalidades
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.
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 já 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
eonBlur
passaram a usar os eventos nativosfocusin
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 eventoonFocus
, note que isso não afetou o comportamento de propagação. No React, o eventoonFocus
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 desetState
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
- Adicione
react/jsx-runtime
ereact/jsx-dev-runtime
para que a nova transformação JSX. (@lunaruan em #18299) - Construa pilhas de componentes a partir de quadros de erro nativos. (@sebmarkbage em #18561)
- Permite especificar
displayName
no contexto para pilhas melhoradas. (@eps1lon em #18224) - Impedir que
'use strict'
vaze nos pacotes UMD. (@koba04 em #19614) - Pare de usar
fb.me
para redirecionamentos. (@cylim em #19598)
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
efocusout
paraonFocus
eonBlur
. (@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
oumemo
retornarundefined
. (@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 elementosvideo
. (@tombrowndev em #18619) - Adicione a propriedade
enterKeyHint
para elementosinput
. (@eps1lon em #18634) - Avisar quando nenhum
valor
é fornecido para<Context.Provider>
. (@charlie1404 em #19054) - Avisa quando os componentes
memo
ouforwardRef
retornamundefined
. (@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
eonWheel
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 umevent.type
incorreto. (@eps1lon em #19561) - Corrigir o
event.relatedTarget
relatado comoundefined
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
eonReset
. (@gaearon em #19333) - Melhore o uso de memória. (@trueadm em #18970)
Servidor React DOM
- Torne o comportamento
useCallback
consistente comuseMemo
para o renderizador do servidor. (@alexmckenley em #18783) - Fix state leaking when a function component throws. (@pmaccart em #19212)
Teste Renderização React
- Melhorar a mensagem de erro
findByType
. (@henryqdineen em #17439)
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
eunstable_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)