A versão 16.0.0, foi lançado em 26 de setembro de 2017, e trouxe mudanças significativas até o momento.
Polêmica com a licença
Por um período os desenvolvedores ficaram preocupados com a ideia da biblioteca ter adotado a licença BSD+Patents. Tudo ficou na paz, quando o React 16 foi disponível sob a licença MIT. A versão 15.6.2 também foi publicado com essa licença, para que não fosse preciso que as aplicações fossem atualizadas imediatamente.
Novo tamanho
Agora mesmo com novas funcionalidades, o tamanho diminuiu cerca de 32%, se comparado com a versão 15.6.1.
Versão 15
- react - 20.7kb (6.9kb com gzip)
- react-dom - 141kb (42.9kb com gzip)
- react + react-dom - 161.7 kb (49.8 kb com gzip)
Versão 16
- react - 5.3kb (2.2kb com gzip)
- react-dom - 103.7kb (32.6kb com gzip)
- react + react-dom - 109 kb (34.8 kb com gzip)
Tratamento de erros
Antes tínhamos o problema que ao ter um erro durante a renderização, toda a árvore de componentes era desmontada. Agora é possível capturar os erros e substituir o componente. Quem não gosta de um try-catch? :)
Temos então, o novo método componentDidCatch, que irá informar o erro para que possamos tratar com facilidade. Identificando um erro, podemos tratar no método render.
1 | componentDidCatch(error, info) { |
Para mais detalhes, confira o artigo oficial sobre o tratamento de erros no React 16.
Novos tipos de retorno de renderização
Ao trabalhar com React, o método render sempre deve retornar um único elemento. Querendo retonar uma lista de elementos, você deve criar um container para eles.
Agora você pode retornar um Array de elementos. Por ser um Array, você ainda precisará adicionar o atributo key aos elementos.
1 | render() { |
E também é possível retornar uma simples String:
1 | render() { |
Portals
Agora é possível inserir um elemento filho em um local diferente no DOM, fora da sua árvore principal.
Exemplo:
1 | <body> |
Com Portals, tendo um componente na div main, será possivel pegar este componente e renderizá-lo na div modal.
Tendo um elemento que irá aparecer na página e reaparecer ao abrir uma modal, seria necessário chamar o componente em dois lugares (na página e na modal) e passar as propriedades para ele. Com Portals basta indicar o elemento que quer usar e onde quer exibí-lo. Querendo alterar alguma propriedade passada para o componente, só será preciso alterar em um lugar.
Mais detalhes na documentação;
Renderização no lado do servidor
Graças a reescrita, a renderização no lado do servidor ficou muito mais rápida. E agora com suporte a streaming, sendo possível enviar os dados de forma melhor e mais ágil para o navegador.
Nesse artigo, pode ser visto as melhorias no SSR.
Atributos personalizados
Atributos informados no HTML ou SVG que não fossem reconhecidos eram ignorados. Agora os mesmos são mantidos.
1 | <!-- nosso código --> |
Nova arquitetura
Agora temos uma reescrita na arquitetura central da biblioteca, sendo conhecida como Fiber. O mesmo é responsável pela maioria dos novos recursos do React 16.
Uma área que está tendo um bom foco é a renderização assíncrona, tendo uma estratégia para programar cooperativamente a renderização, entregando periodicamente a execução ao navegador. Com a renderização assíncrona, as aplicações são mais responsivas porque o React evita o bloqueio da árvore principal. Nessa versão 16.0.0 não foi ativado nenhum recurso assíncrono, para facilitar a migração para essa versão.
Confira um exemplo de problema de renderização assíncrona.
Depreciações, mudanças, empacotamento e requisitos
Depreciações
Para hidratar um container renderizado pelo servidor agora tem uma API explicita. Renderizando o HTML pelo servidor, use ReactDOM.hydrate ao invés de ReactDOM.render. Use ReactDOM.render se renderizar pelo lado do cliente.
O suporte ao React Addons foi descontinuado e com exceção do react-addons-perf que terá uma versão nova, os outros addons não serão atualizados. react-addons-perf não funciona no React 16, e é encorajado usar as ferramentas do navegador para medir performance.
Mudanças
O React 16 depende dos tipos de coleção Map e Set. Se você precisa dar suporte para navegadores e dispositivos antigos que não suportam nativamente (por exemplo, IE <11) ou que tenham implementações não compatíveis (por exemplo, IE 11), será necessário incluir um polyfill na aplicação, como core-js ou babel-polyfill. Confira mais sobre o assunto.
Algumas mudanças que podem causar quebras em relação às versões anteriores:
- ReactDOM.render e ReactDOM.unstable_renderIntoContainer agora retornam null se forem chamados de dentro de um método do ciclo de vida do componente. Para contornar isso, você pode usar portals ou refs.
- Chamar setState com null não dispara mais atualizações
- Chamar setState diretamente dentro de render sempre causa atualizações.
- Callbacks de setState agora são disparados após componentDidMount ou componentDidUpdate.
- Ao trocar por , B.componentWillMount agora vai sempre acontecer antes de A.componentWillUnmount. Antes, A.componentWillUnmount podia inicializar primeiro em certos casos.
- Antes, mudar a referência de um componente sempre iria desmontar a referência antes que o renderização do componente fosse chamada. Agora, a referência é alterada depois, quando aplicadas as mudanças no DOM.
- componentDidUpdate não recebe mais o parâmetro prevContext.
- O renderizador superficial não é mais chamado no componentDidUpdate porque as referências DOM não estão disponíveis. Isso também o torna consistente com componentDidMount(que também não é chamado nas versões anteriores).
Empacotamento
Agora não existe mais react/lib/ e react-dom/lib/. Os nomes/caminhos mudaram para enfatizar a diferença entre os builds de produção e desenvolvimento:
- react/dist/react.js → react/umd/react.development.js
- react/dist/react.min.js → react/umd/react.production.min.js
- react-dom/dist/react-dom.js → react-dom/umd/react-dom.development.js
- react-dom/dist/react-dom.min.js → react-dom/umd/react-dom.production.min.js
Considerações finais
Muitas mudanças boas vieram e o React continua sendo muito usado nas aplicações. Pode conferir o artigo completo no blog oficial sobre a versão 16.0.0.