React: React Fire: Modernizando o React DOM

Criado em 31 ago. 2018  ·  227Comentários  ·  Fonte: facebook/react


Para obter o status mais recente, consulte uma atualização de 5 de junho de 2019: https://github.com/facebook/react/issues/13525#issuecomment -499196939


Este ano, a equipe do React se concentrou principalmente em melhorias fundamentais no React .

À medida que este trabalho está se aproximando da conclusão, estamos começando a pensar em como devem ser os próximos grandes lançamentos do React DOM. Existem alguns problemas conhecidos , e alguns deles são difíceis ou impossíveis de corrigir sem grandes mudanças internas.

Queremos desfazer erros do passado que causaram inúmeras correções de acompanhamento e criaram muita dívida técnica. Também queremos remover algumas abstrações no sistema de eventos que foram praticamente intocadas desde os primeiros dias do React, e é uma fonte de muita complexidade e tamanho de pacote.

Estamos chamando esse esforço de "React Fire".

🔥 Reagir ao Fogo

React Fire é um esforço para modernizar o React DOM. Nosso objetivo é tornar o React mais alinhado com o funcionamento do DOM, revisitar algumas decisões controversas do passado que levaram a problemas e tornar o React menor e mais rápido.

Queremos lançar este conjunto de mudanças em um futuro lançamento principal do React porque algumas delas infelizmente serão quebradas. Mesmo assim, achamos que valem a pena. E temos mais de 50 mil componentes no Facebook para nos manter honestos sobre nossa estratégia de migração. Não podemos nos dar ao luxo de reescrever o código do produto, exceto algumas correções direcionadas ou codemods automatizados.

Estratégia

Existem algumas coisas diferentes que compõem nosso plano atual. Podemos adicionar ou remover algo, mas aqui está o pensamento até agora:

  • Pare de refletir os valores de entrada no atributo value (https://github.com/facebook/react/issues/11896). Isso foi originalmente adicionado no React 15.2.0 via https://github.com/facebook/react/pull/6406. Era muito solicitado porque o modelo conceitual do DOM das pessoas é que o value que eles veem no inspetor DOM deve corresponder ao atributo value JSX. Mas não é assim que o DOM funciona. Quando você digita em um campo, o navegador não atualiza o atributo value . React também não deveria fazer isso. Descobriu-se que essa mudança, embora provavelmente útil para alguns códigos que dependem de seletores CSS, causou uma cascata de bugs - alguns deles ainda não corrigidos até hoje. Algumas das consequências dessa mudança incluem: https://github.com/facebook/react/issues/7179 , https://github.com/facebook/react/issues/8395 , https://github.com/facebook /react/issues/7328 , https://github.com/facebook/react/issues/7233 , https://github.com/facebook/react/issues/11881 , https://github.com/facebook/react /issues/7253 , https://github.com/facebook/react/pull/9584 , https://github.com/facebook/react/pull/9806 , https://github.com/facebook/react/pull /9714 , https://github.com/facebook/react/pull/11534 , https://github.com/facebook/react/pull/11746 , https://github.com/facebook/react/pull/12925 . Neste ponto, claramente não vale a pena continuar lutando contra o navegador, e devemos reverter isso. A parte positiva dessa jornada é que, graças ao trabalho incansável de nossos colaboradores do DOM ( @nhunzaker , @aweary , @jquense e @philipp-spiess ), agora temos dispositivos de teste DOM detalhados que nos ajudarão a evitar regressões.

  • Anexe eventos na raiz do React em vez do documento (https://github.com/facebook/react/issues/2043). Anexar manipuladores de eventos ao documento se torna um problema ao incorporar aplicativos React em sistemas maiores. O editor Atom foi um dos primeiros casos que se depararam com isso. Qualquer grande site também desenvolve casos de borda muito complexos relacionados a stopPropagation interagindo com código não React ou entre raízes React (https://github.com/facebook/react/issues/8693, https://github .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). Também desejaremos anexar eventos a cada raiz para que possamos fazer menos verificações de tempo de execução durante as atualizações.

  • Migre de onChange para onInput e não faça polyfill para componentes não controlados (https://github.com/facebook/react/issues/9657). Consulte o problema vinculado para obter um plano detalhado. Tem sido confuso que o React use um nome de evento diferente para o que é conhecido como evento input no DOM. Embora geralmente evitemos fazer grandes mudanças como essa sem benefícios significativos, neste caso também queremos alterar o comportamento para remover alguma complexidade que é necessária apenas para casos extremos, como a mutação de entradas controladas. Portanto, faz sentido fazer essas duas mudanças juntas e usar isso como uma oportunidade para fazer onInput e onChange funcionarem exatamente como os eventos DOM funcionam para componentes não controlados.

  • Simplifique drasticamente o sistema de eventos (https://github.com/facebook/react/issues/4751). O sistema de eventos atual quase não mudou desde sua implementação inicial em 2013. Ele é reutilizado em React DOM e React Native, por isso é desnecessariamente abstrato. Muitos dos polyfills que ele fornece são desnecessários para navegadores modernos, e alguns deles criam mais problemas do que resolvem. Ele também é responsável por uma parte significativa do tamanho do pacote React DOM. Não temos um plano muito específico aqui, mas provavelmente faremos um fork do sistema de eventos completamente e, em seguida, veremos o quão mínimo podemos torná-lo se ficarmos mais próximos do que o DOM nos dá. É plausível que nos livremos completamente dos eventos sintéticos. Devemos parar de borbulhar eventos como eventos de mídia que não borbulham no DOM e não têm uma boa razão para borbulhar. Queremos manter alguns recursos específicos do React, como borbulhar através de portais, mas tentaremos fazer isso por meios mais simples (por exemplo, re-despachando o evento). Eventos passivos provavelmente farão parte disso.

  • classNameclass (https://github.com/facebook/react/issues/4331, veja também https://github.com/facebook/react/issues/13525#issuecomment- 417818906 abaixo). Isso foi proposto inúmeras vezes. Já estamos permitindo passar class para o nó DOM no React 16. A confusão que isso está criando não vale as limitações de sintaxe contra as quais está tentando se proteger. Não faríamos essa mudança por si só, mas combinada com tudo o mais acima faz sentido. Observe que não podemos permitir ambos sem avisos, porque isso dificulta muito o manuseio de um ecossistema de componentes. Cada componente precisaria aprender a lidar com ambos corretamente, e existe o risco de eles entrarem em conflito. Como muitos componentes processam className (por exemplo, anexando a ele), é muito propenso a erros.

Trocas

  • Não podemos fazer algumas dessas alterações se pretendemos continuar expondo as APIs privadas atuais do sistema de eventos React para projetos como React Native Web. No entanto, o React Native Web precisará de uma estratégia diferente, independentemente, porque o React Fabric provavelmente moverá mais do sistema de resposta para o lado nativo.

  • Podemos precisar descartar a compatibilidade com alguns navegadores mais antigos e/ou exigir mais polyfills independentes para eles. Ainda nos preocupamos com o suporte ao IE11, mas é possível que não tentemos suavizar algumas das diferenças existentes no navegador — que é a postura adotada por muitas bibliotecas de interface do usuário modernas.

Plano de lançamento

Nesta fase, o projeto é muito exploratório. Não sabemos ao certo se todas as coisas acima vão dar certo. Como as mudanças são significativas, precisaremos testá-las no Facebook e testá-las de maneira gradual. Isso significa que vamos introduzir um sinalizador de recurso, bifurcar parte do código e mantê-lo ativado no Facebook para um pequeno grupo de pessoas. As versões de código aberto 16.x manterão o comportamento antigo, mas no master você poderá executá-lo com o sinalizador de recurso ativado.

Pretendo trabalhar no projeto na maior parte, mas gostaria muito de mais discussões e contribuições de @nhunzaker , @aweary , @jquense e @philipp-spiess que foram colaboradores estelares e conduziram amplamente o React DOM enquanto estávamos trabalhando em fibra. Se houver alguma área em que você esteja particularmente interessado, informe-me e resolveremos isso.

Há coisas prováveis ​​que eu perdi neste plano. Estou muito aberto a comentários e espero que este artigo seja útil.

DOM React Core Team Big Picture

Comentários muito úteis

Eu amo cada um desses pontos, exceto a mudança className . Parece totalmente contraditório com o objetivo que os outros pontos estão buscando (alinhar-se com a API DOM). O React se vincula a propriedades DOM, não a atributos HTML (isso é mesmo articulado no primeiro ponto). A propriedade DOM Element é denominada className , não class . Então, por que seria chamado class em React?

Todos 227 comentários

Eu amo isto. Reduzir o tamanho do pacote e o prop "class" são mudanças que serão muito bem-vindas.

Ótimo trabalho!

🙂

Atenção, autores de bibliotecas! 🤣

Excelente!

className → a classe é fantástica

E todos os outros? Parece estranho ainda estar fazendo clipPath , htmlFor , tabIndex , etc.

Adotar class é um grande avanço para tornar a biblioteca mais amigável para iniciantes. Parabéns.

Isso é incrível. Estou tão curioso para saber como a mudança para class está realmente funcionando com adereços.

Parece que ({ class }) => <div class={class} /> inicialmente apresentaria um problema de palavra-chave reservada?

Esta é uma notícia fantástica, obrigado @gaearon!

Eu amo cada um desses pontos, exceto a mudança className . Parece totalmente contraditório com o objetivo que os outros pontos estão buscando (alinhar-se com a API DOM). O React se vincula a propriedades DOM, não a atributos HTML (isso é mesmo articulado no primeiro ponto). A propriedade DOM Element é denominada className , não class . Então, por que seria chamado class em React?

Fantástico! Você tem uma meta para a redução do tamanho do pacote?

👏

E todos os outros? Parece estranho ainda estar fazendo clipPath, htmlFor, tabIndex, etc.

Estou aberto à discussão, mas diria que essas mudanças não valem a pena (exceto for talvez).

Eu acho que uma reescrita do sistema de eventos é o aspecto mais interessante disso. Há uma oportunidade significativa para reduzir o tamanho do pacote e facilitar as contribuições da comunidade.

Vamos fazer isso!

Será que valeria a pena trabalhar também no lançamento do JSX 2.0 ao mesmo tempo? As pessoas vão precisar reaprender um punhado de coisas de qualquer maneira. Talvez seja melhor ter que reaprender um monte de uma vez em vez de algumas coisas duas vezes ao longo de um período de tempo? Apenas um pensamento que ocorreu enquanto eu lia isso.

Eu amo todos esses pontos, exceto a mudança className. Parece totalmente contraditório com o objetivo que os outros pontos estão buscando (alinhar-se com a API DOM). O React se vincula a propriedades DOM, não a atributos HTML (isso é mesmo articulado no primeiro ponto).

E ainda se passarmos um par chave/valor desconhecido ele será tratado como um atributo desde o React 16. Então já estamos inconsistentes. Além disso, meu comentário foi sobre os usuários estarem errados em esperar que o React defina o atributo value . Se a API React usa o nome do atributo ou o nome da propriedade em sua API é totalmente ortogonal.

Defendo seu lado desse argumento há anos, mas acho que agora esse é um atrito que não vale a pena. Você não ganha nada com isso. Apenas deixar as pessoas usarem class não tem efeitos negativos, exceto que não funciona com a desestruturação e o custo de migração. Todo mundo reclama disso quando aprende React. Acho que fazer o que as pessoas esperam neste caso é mais importante do que ser pedante. E já que estamos mudando outras coisas do DOM de qualquer maneira, vamos agrupar isso.

Enquanto o React Fire for muito rápido... 👍

Essas mudanças são todas fantásticas. Estou muito animado com isso e suas implicações para react-testing-library . Em particular, eventos vinculados à raiz de reação (ou talvez até mesmo descartar a delegação de eventos, pois pode não ser mais necessário em ambientes modernos?), potencialmente removendo/reescrevendo eventos sintéticos e onChange -> onInput melhorará seriamente a implementação de react-testing-library e a experiência no uso da ferramenta.

Eu adoraria fornecer feedback sobre isso enquanto está sendo implementado.

talvez até abandone a delegação de eventos, pois pode não ser mais necessário em ambientes modernos

Consideramos isso, mas achamos que isso pode ser uma simplificação excessiva. A delegação de eventos nos permite evitar a configuração de vários ouvintes para cada nó na renderização inicial. E trocá-los em atualizações. Esses aspectos não devem ser ignorados. É provável que haja mais benchmarking a ser feito lá.

@tannerlinsley ({ class: className }) => <div class={className} /> infelizmente isso matará a notação de mão curta do objeto jsx 2.0 ( <div class /> ), mas que assim seja ...

Seria super, super legal se class pudesse finalmente pegar objetos e arrays ao lado de strings.

Você tem uma meta para a redução do tamanho do pacote?

Descartar um terço do React DOM seria bom. Veremos. É difícil dizer cedo, mas vamos fazer o nosso melhor.

Uau, esta é uma enumeração de quase todas as decisões de design que menciono quando as pessoas me perguntam sobre os contras do React.

Amo a direção que isso está tomando.

Qual seria o caminho de atualização para bibliotecas que usam className e desejam oferecer suporte a várias versões do React?

@gaearon Talvez não seja grande coisa, hoje é bom dizer "props são propriedades DOM e não atributos HTML", agora será "exceto className, esse é o nome HTML". Eu também gostaria de poder copiar/colar SVG sem 10 minutos de mexer com atributos para combinar com os do React

E htmlFor ?

Parece que a transição className -> class terá que ser feita com muito cuidado, provavelmente por um longo período de tempo. Isso causará muitos problemas para o ecossistema, pois praticamente todos os componentes precisarão ser alterados - mesmo os muito triviais. Isso é bom se você "possui" o código e há um codemod, mas quando você depende de bibliotecas de terceiros, fica à mercê dos mantenedores.

O resto das mudanças parecem ter um risco relativamente baixo do ponto de vista do ecossistema, mas se livrar de className realmente causará muita dor. Parece que deve ser possível dividir isso em um problema separado e lançá-lo em um cronograma diferente do restante das 🔥 mudanças.

concordo com @felixfbecker
Tudo parece incrível e melhoraria a qualidade tanto para desenvolvedores quanto para usuários, mas a mudança className.

Ser capaz de desconstruir todas as propriedades, mas certamente causaria mais confusão e seria mais difícil de explicar para novos usuários do que eles precisam usar className porque class é uma palavra-chave (que eles podem ver claramente quando o erro é cometido, pois é colorido de maneira diferente) . Trabalhar em torno da classe na desconstrução requer a introdução de uma nova sintaxe ou uma maneira completamente diferente de ler essa propriedade específica que só funcionaria até que você precisasse usar uma propriedade rest.
Ele cria muitos problemas apenas para salvar quatro caracteres.

@felixfbecker poderia ser class / for em JSX e className / htmlFor na versão JS?

<label class="foo" for="bar">..</label>

seria

React.createElement('label', {className: 'foo', htmlFor: 'bar'}, '..')

Ótimo plano! Bom aqui isso! 👏👏👏

Isso é incrível, mal posso esperar para me aprofundar nas coisas novas.

Simplifique drasticamente o sistema de eventos (#4751).

Agora o react não pode delegar o manipulador para elementos personalizados, sem estender a definição do ReactDOM. https://github.com/facebook/react/issues/9242

Isso significa que o React não pode definir o manipulador personalizado no elemento personalizado como <x-component onMyEvent={ev => {...}} />

@gaearon
Você tem algum plano sobre isso?

Todas essas mudanças são excelentes, mas a maior meta mudança de todas é a redução de tamanho na minha opinião. O React tem um DX médio, mas é gordo o suficiente para que baixá-lo e analisá-lo em redes médias e, em particular, em dispositivos móveis, seja um problema.

Poderíamos ter tudo!

Reescrever a delegação do evento abriria a porta para a correção #1254; onde alguns eventos degradam o perf para o nó ao qual estão anexados (o que para React significa todo o aplicativo).

Além disso, como um tiro no escuro, você considerou ter adereços sintéticos dataSet? Não ser capaz de digitar props HTML permitidos (por causa de data-*) leva a uma tonelada de bugs ao encaminhar props para os nós DOM. Os componentes React atualmente tipados precisam escolher entre tipos exatos para props e permitir atributos de dados.

Estou animado

@ryanflorence Um pouco offtop, mas é meio triste que ninguém (até onde eu saiba) teve a ideia de fazer um transformador html/css/svg -> jsx para facilitar migrações para React com tantas mudanças triviais para mapear HTML attrs para adereços do React. Tantas horas de trabalho desperdiçadas realizando principalmente localizar e substituir :(

É muito estranho ver o seguinte na mesma edição (e nos comentários):

Nosso objetivo é tornar o React melhor alinhado com a forma como o DOM funciona
nome da classe → classe
Parece estranho ainda estar fazendo clipPath, htmlFor, tabIndex, etc.

Quando todos esses são contrapartes diretas das APIs DOM

E este argumento não passa na reunião:

Defendo seu lado desse argumento há anos, mas acho que agora esse é um atrito que não vale a pena. Você não ganha nada com isso. Apenas deixar as pessoas usarem a classe não tem efeitos negativos, exceto

O React sempre foi apenas uma camada muito fina em cima do JS. Portanto, tudo o mais além dos colchetes angulares do JSX era JS _e_ tinha uma contrapartida direta nas APIs DOM para coisas diretamente relacionadas ao DOM: className , clipPath , htmlFor , tabIndex etc. etc. etc.

Com a decisão de introduzir class React deixa de ser uma camada fina ( class é uma palavra reservada em JS) e rompe com o objetivo declarado de ser mais compatível com APIs DOM.

É especialmente chocante ver que você deseja "Migrar de onChange para onInput" porque é inconsistente com o DOM _e_ se torna inconsistente com o DOM migrando className -> class .

Além disso, isso abre uma lata cheia de worms, pois as pessoas exigirão (e já estão exigindo) alterações em outras partes. Apenas nos comentários: por que usamos dataset em vez de data-* ? Talvez porque data-* não seja um JS válido (muito parecido com class ) e porque é consistente com as APIs DOM ? Por que não mudamos htmlFor ? Porque for é uma palavra reservada e htmlFor está em APIs DOM? etc etc etc etc

E ainda se passarmos um par chave/valor desconhecido ele será tratado como um atributo desde o React 16. Então já estamos inconsistentes.

@gaearon, que também é a razão pela qual o React é a única biblioteca com pontuação ruim no teste de interoperabilidade CustomElements Everywhere: https://custom-elements-everywhere.com/
E há muitos problemas pedindo para alterá-lo: https://github.com/facebook/react/issues/11347 , https://github.com/facebook/react/issues/7249 , https://github.com/facebook /react/issues/9230

Isso pode não ser um problema, mas a semelhança do React Fire com o React Fiber será confusa para falantes não nativos de inglês? Muitas vezes pensei que a Estação Newark Penn e a Estação Penn de Nova York estando na mesma linha de trem aqui em Nova York era uma piada particularmente cruel para os turistas.

Se for uma preocupação real, você pode chamá-lo de Reagir Chama e ainda manter o fogo 🔥 emoji.

Reescrever a delegação do evento abriria a porta para a correção #1254; onde alguns eventos degradam o perf para o nó ao qual estão anexados (o que para React significa todo o aplicativo).

Consertar #1254 de alguma forma é definitivamente algo que eu gostaria de ver.

Além disso, como um tiro no escuro, você considerou ter adereços sintéticos dataSet?

Não quero me comprometer com algo assim agora porque há uma superfície maior. Interface mais rica para DOM ( ariaSet , dataSet , classList ) faz sentido, mas não está claro quanto queremos investir nisso no React DOM, em comparação com uma biblioteca de nível superior que oferece uma API DOM mais rica. Como essas mudanças são mais cosméticas, mas têm uma área de superfície alta, eu as adiaria.

Reaja Blazing 🔥

@ryanflorence Um pouco offtop, mas é meio triste que ninguém (até onde eu saiba) teve a ideia de fazer um transformador html/css/svg -> jsx para facilitar migrações para React com tantas mudanças triviais para mapear HTML attrs para adereços do React. Tantas horas de trabalho desperdiçadas realizando principalmente localizar e substituir :(

@jxub
https://transform.now.sh/html-to-jsx/

Tão empolgados com as novas mudanças, vocês humanos do Facebook estão fazendo história com essa migração. 50k componentes serão migrados para o React Fire?
Suas suítes de teste devem ser tão apertadas <3

a semelhança do React Fire com o React Fiber será confusa para falantes não nativos de inglês?

talvez para pessoas com deficiência auditiva também (ou aquelas com outras condições que afetam a discriminação de palavras)

Obrigado por compartilhar @gaearon , isso é incrível!

Eu adoraria ver uma versão JSX 2.0 resolvendo o problema de espaço em branco e novas linhas que ocorre quando compilamos nosso código com Babel e Typescript.

Existem diferentes questões abertas e eu tentei contribuir, mas fui repreendido porque a equipe do React precisa revisar tudo em torno do JSX.

Este problema está relacionado ao dom de qualquer maneira, pois a forma como traduzimos jsx para js não permite o que o w3c diz.

Este é o problema https://github.com/facebook/jsx/issues/19

Meu comentário está no final.

Acho que className está ok. Deixe ser o que é. Não adicione insulto à injúria.

Alguém pode esclarecer como isso afeta os manipuladores existentes?

Parar de refletir os valores de entrada no atributo value

O React ainda terá entradas controladas com atualizações precisas de event.target.value nos manipuladores, ou isso afeta apenas a leitura de valores de refs e nós DOM?

@nickmccurdy afeta o que você vê nas ferramentas de desenvolvimento do navegador

@tomdale Reagir Ember 🔥

Agradável! Estou esperando para ver a lista completa de mudanças no React 17.
Acredito que será uma nova era do ReactJS. 🔥⚛️.

@tomdale Hmm: Fio, Fibra, Tecido; talvez outro termo relacionado a roupas possa ser usado? 😆

E ainda se passarmos um par chave/valor desconhecido ele será tratado como um atributo desde o React 16. Então já estamos inconsistentes.

@gaearon, que também é a razão pela qual o React é a única biblioteca com pontuação ruim no teste de interoperabilidade CustomElements Everywhere: https://custom-elements-everywhere.com/

Não, esse não é o motivo (elementos personalizados e normais são caminhos de código completamente separados). A razão é que já tínhamos o comportamento antigo e não queríamos quebrar a retrocompatibilidade a menos que o novo comportamento fosse sólido. Acho que faria sentido abordar uma melhor interoperabilidade de elementos personalizados como parte desse guarda-chuva.

a semelhança do React Fire com o React Fiber será confusa para falantes não nativos de inglês?

Ambos são codinomes internos e não têm nenhum significado quando os projetos são concluídos. React Fire é apenas um esforço para tornar o React DOM melhor - e quando estiver pronto para produção, será apenas React DOM.

O React ainda terá entradas controladas com atualizações precisas de event.target.value em handlers, ou isso afeta apenas a leitura de valores de refs e DOM Nodes?

Sim, porque event.target.value é uma propriedade . Estamos falando sobre parar de atualizar atributos . O que nenhuma outra biblioteca popular faz (AFAIK) e que causa inúmeros problemas. Isso não deve afetar seu código, a menos que você esteja confiando em seletores CSS no valor (o que provavelmente é ruim de qualquer maneira).

Agradável! Estou esperando para ver a lista completa de mudanças no React 17.

Observe que não estamos nos comprometendo com isso estar pronto até 17. Pode ser 18. Ou 19. 😅

É bom ver um desenvolvimento constante em uma biblioteca tão boa como React. 🎉 class vai deixar a usabilidade muito melhor, vale a pena imo

@gaearon

elementos personalizados e normais são caminhos de código completamente separados

Isso em si parece algo para consertar também. Existe alguma razão para não tratar todos os elementos da mesma forma? Essa é a intenção das especificações HTML e DOM.

@justinfagnani Como discutido anteriormente, o motivo pelo qual não fizemos isso na época foi porque não havia convenção sobre como definir uma propriedade ou um atributo - e havia o risco de que, usando uma verificação, corrêssemos o risco de torná-la impossível para a plataforma web adicionar novas propriedades ao protótipo. Acho que agora já existe algum tipo de consenso nas RFCs e PRs em que @robdodson está trabalhando, e provavelmente podemos pegar a partir daí.

👍 🔥 🔥 🔥

O React Fire também deve nos permitir aplicar algumas das otimizações de desempenho inteligentes que o Inferno tem - mas não foi possível aplicar devido a alterações importantes. Tempos emocionantes :)

LGTM

Relacionado com a proposta de renomeação className -> class : Eu adoraria uma propriedade classes que aceitasse um array de strings. Isso me pouparia o trabalho de muita manipulação de strings (ou o uso de classnames ) em meus componentes.

Eu acho que a única desvantagem de um prop classes seria que arrays contendo as mesmas strings na mesma ordem causariam uma nova renderização no componente puro, enquanto uma string das mesmas classes CSS não. Honestamente, porém, parece um problema menor. Eu acho que a maioria dos desenvolvedores de React já conhece as vantagens de arrays e objetos em props.

@gaearon tem planos para compatibilidade com versões anteriores? Talvez siga o mesmo caminho do React Fiber, adicionando avisos sobre as mudanças e dando tempo para que grandes bases de código atualizem isso sem perder novas atualizações.

Em relação class e className .

Eu sei que não conseguiremos um amplo acordo sobre isso, seja qual for o caminho que tomarmos. As pessoas têm opiniões muito fortes sobre isso. Quero compartilhar como estou pensando sobre isso, na esperança de que seja útil.

A API do componente deve parecer idiomática

Existe um argumento comum de que o React "combina com o JavaScript" e, portanto, className é o preferido. Acho que essa afirmação é sutilmente mal compreendida, então gostaria de me concentrar um pouco nela.

Em React, antes de tudo, nos importamos que usar um componente React pareça JavaScript idiomático . Isso significa que, se eu usar um componente hipotético <Table> , espero que seus adereços sejam camelCase:

<Table
  rowHeight={10}
  headerBorderInset={5}
  renderRow={this.renderRow}
/>

Não espero ver nomes de props como row_height ou row-height na API pública de um componente . Os adereços do componente são um objeto (como um "saco de opções"), e geralmente esperamos que essas opções sejam camelCase . Isso pode não ser sempre idiomático no DOM, mas o DOM não é muito consistente em muitos lugares. React se alinha com o ecossistema JavaScript que usa predominantemente camelCase .

Mas e o DOM? É aqui que fica espinhoso.

Propriedades DOM não são apenas "atributos em JS"

No DOM, temos atributos e propriedades. Atributos são as coisas que você normalmente vê em HTML. Propriedades são as coisas que você normalmente define do JS. Mas, crucialmente, as APIs DOM existem tanto para definir propriedades quanto para definir atributos — e nem sempre estão definindo a mesma coisa.

node.value = 10; // setting a property
node.setAttribute('value', '10'); // setting an attribute

Em muitos casos não importa. Em alguns casos sim. Mas talvez não da maneira que se poderia pensar usando React (que tem uma abstração sobre ambos).

React não é apenas definir propriedades

Um equívoco comum é que, como o React atualmente usa a convenção camelCase para a maioria das props do DOM, isso significa que o React está configurando as propriedades do DOM. Isto está errado.

Na verdade, o React está atualmente usando atributos para quase todos os adereços que ele suporta. Em alguns casos, como value , isso está causando problemas (que, como discuti, queremos reverter). Em outros casos, isso é realmente ótimo — porque não precisamos incluir uma lista de propriedades suportadas no pacote React. Usar atributos sob o capô foi o que permitiu uma grande redução de tamanho no React 16.

Meu ponto aqui é que se o React usa propriedades ou atributos internamente é um detalhe de implementação - e não tem nada a ver com se o elemento _API_ do React DOM deve estar usando nomes de propriedades, nomes de atributos ou até mesmo alguns outros nomes que fazem sentido.

Ainda assim, vamos apenas usar nomes de propriedades?

Ok, propriedades e atributos são um detalhe de implementação. Mas por que não apenas padronizar o uso de nomes de propriedade DOM, já que eles foram feitos especificamente "para JavaScript"? Não é assim que a API React é projetada hoje?

Bem, não exatamente. Apenas uma das props enumeradas abaixo corresponde a uma propriedade de objeto DOM real:

<div
  tabIndex={1}
  data-id="123"
  aria-live="polite"
  nopin="nopin"
  itemType="http://schema.org/Movie"
  onClick={function() { alert('hi') }}
/>

Ironicamente, a única prop acima que tem uma propriedade DOM real com o mesmo nome correspondente a ela ( tabIndex se você não tiver certeza) está sendo definida pelo React como um atributo!

Então, a essa altura, você provavelmente verá que não é claro nem consistente. Em alguns casos, as propriedades não existem (como para atributos personalizados e não padrão), em alguns casos o React pode fornecer uma API mais rica ( data- vs dataSet ), mas atualmente não.

Em alguns casos, o React intencionalmente escolhe desviar ( onClick na propriedade React vs onclick DOM) porque faz mais sentido para componentes personalizados do React. Isso ocorre porque os componentes do React geralmente expõem manipuladores de eventos mais complexos como onItemClick . Seria muito inconsistente se você escrevesse <Button onclick> mas <Table onItemClick> . E <Table onitemclick> não é camelCase, o que queríamos evitar em uma API de componente.

Acima, expliquei que o React já não é consistente sobre "sempre usar o nome da propriedade DOM", que o React nem mesmo usa propriedades internamente (então essa regra geral também não descreve a mecânica real), e que em muitos casos, as propriedades DOM simplesmente não existem, então temos que continuar permitindo o nome do atributo.

Se não forem nomes de propriedades, vamos ser consistentes e usar nomes de atributos?

Então, por que não usar apenas nomes de atributos? Isso pode ser plausível. Mas agora nos deparamos com a primeira consideração que trouxemos. Usar um componente React deve parecer JavaScript idiomático . Mas muitas vezes os componentes encaminham pelo menos alguns adereços para o elemento DOM subjacente.

<Button
  borderColor='red'
  tabIndex={1}
 />

 // renders...

 <button
   tabIndex={1}
/>

Seria estranho para um Button personalizado aceitar adereços com capitalização inconsistente:

<Button
  borderColor='red'
  tabindex={1}
 />

Isso força o consumidor a sempre lembrar se uma certa prop é uma prop real do DOM, ou apenas uma parte do contrato do componente. Mesmo essa distinção é confusa - um componente pode escolher primeiro passar por um certo suporte, mas depois começar a usá-lo para alguma lógica extra. Onde você coloca o limite entre "props DOM" e "outros adereços"?

Eu acho que esta é a principal razão pela qual é desejável que adereços como tabIndex , cellSpacing e a maioria dos outros adereços relacionados ao DOM sigam a convenção camelCase. É porque eles geralmente acabam em APIs de componentes.

Queremos tornar mais fácil para componentes personalizados como Button envolvê-los e encaminhá-los sem "traduzi-los" para o nome do atributo no ponto em que fluem para o DOM e sem introduzir props não camelCase em um API de componente personalizado.

Isso também explica por que props como data-* , aria-* e atributos personalizados são exceções razoáveis ​​(mesmo que possamos fazer APIs mais ricas para eles). Eles raramente são passados ​​para componentes personalizados. Normalmente, eles são muito acoplados ao DOM para serem úteis em componentes personalizados — e, em vez disso, eles se tornam um detalhe de implementação de algo como <Modal> ou <Button> com uma API camelCase mais rica.

Propriedades do React já não correspondem às propriedades do DOM

Se a convenção "nome da propriedade DOM" não funcionou, precisamos de outra coisa. O que é isso? Poderia ser "versão camelCase do nome do atributo"? Parece que isso quase sempre já dá certo.

Se isso soa muito radical, considere que já estamos fazendo isso. Apoiamos algo chamado srcSet . Mas o nome da propriedade DOM é srcset . Temos autoCapitalize mas a propriedade DOM é chamada autocapitalize . Temos autoFocus mas a propriedade DOM é autofocus .

Já estamos nos desviando dos nomes de propriedade do DOM quando eles não correspondem à convenção JavaScript camelCase. O que nos leva a class .

Finalmente: className vs class

Parte da justificativa original para torná-lo className foi porque o React estava configurando propriedades DOM, e className é o nome da propriedade DOM.

No entanto, como expliquei acima, o React não usa mais propriedades, exceto três ou quatro casos especiais. Mais importante, o React nem mesmo usa consistentemente nomes de propriedades DOM - em vez disso, ele usa nomes que parecem naturais quando usados ​​em JavaScript, independentemente da inconsistência de nomenclatura interna em atributos DOM e nomes de propriedades. E isso é porque o React se preocupa mais em manter nomes de props para componentes personalizados com a sensação de "JavaScripty". Nesse sentido, tabindex não é "JavaScripty" — mas class e className são.

Outro argumento contra class no início era que um código como este não era ES3 válido (relevante para o IE8):

// Not valid in ES3
// Valid in ES5
var props = { class: 'foo' };

Mas a maioria não escreve mais ES3. Ou você está usando uma cadeia de ferramentas como o Babel ou provavelmente está mirando no IE9+ – o React nem suporta o IE8 agora.

Portanto, o único inconveniente que resta com class é que você não pode escrever isso:

// Not valid at all :-(
const class = props.class;
const { class } = props;

Mas acho que com o tempo, esse argumento não é forte o suficiente por si só. O React não força você a usar a desestruturação ou usar esse nome de variável específico e escrever algo como

// Valid
const {class: cls} = foo;
const cls = props.class;

não é muito mais esforço.

Normalmente as pessoas passam class para baixo com muito mais frequência do que lê-lo porque muitos componentes contêm mais de um <div> interno ou outros elementos de host. Então você acaba escrevendo <div className> com muito mais frequência do que querendo desestruturar class . E assim a mudança para class economizaria mais digitação no teclado do que introduziria.

Há outro ponto importante aqui.

Passar class por muitos níveis não é um ótimo padrão por si só. É necessário para bibliotecas, mas no código do aplicativo geralmente leva a componentes frágeis. Aqueles cujos estilos quebram o tempo todo porque há uma centena de sites de chamadas diferentes, cada um anexando uma classe diferente, causando bugs em cascata. Portanto, não está claro o quão valioso é incentivar a desestruturação class em primeiro lugar. Eu acho que é bom que você precise escrever mais uma linha de código para lê-lo a partir de props (ou você pode simplesmente usar props.class e não pensar nisso).

Se você está escrevendo um componente que está muito próximo do DOM (e, portanto, faz sentido que ele receba class como prop), você provavelmente deseja encaminhar outras props também. Então você pode usar a sintaxe rest na desestruturação:

// Valid in ES2018

function Button({ color, ...rest }) {
  const buttonClass = rest.class +  ' Button-' + color;
  return <button {...rest} class={buttonClass} />
}

E se você não precisasse modificá-lo, então você poderia simplesmente ter encaminhado {...rest} sem sequer ler class dele. Portanto, a limitação de desestruturação pode ajudar a incentivar um melhor design de componentes.

Por que não ambos?

why not both

Finalmente, não podemos apenas apoiar class e className ? De certa forma, já o fazemos, mas o React grita com você por isso com um aviso. Há uma razão para isto.

Se oferecermos suporte a ambos sem avisos, a comunidade se dividirá sobre qual usar. Cada componente no npm que aceita uma prop de classe terá que se lembrar de encaminhar ambos. Se mesmo um componente no meio não funcionar e implementar apenas um suporte, a classe se perde - ou você corre o risco de acabar com class e className na parte inferior "discordando" de cada outro, sem que o React resolva esse conflito. Então, achamos que isso seria pior do que o status quo e queremos evitar isso.

Resumo

Se o React fosse de código aberto hoje, parece que os prós de permitir class (mais próximo conceitualmente do que a maioria das pessoas espera, menos digitação para o prop mais comumente usado) superam as desvantagens (um pouco mais de digitação para interceptá-lo - em em quais casos você provavelmente desejará apenas o operador de propagação de qualquer maneira).

O que costumávamos ver como desvantagens (inconsistentes com as propriedades do DOM) é discutível porque não definimos mais as propriedades do DOM, nem mesmo nos esforçamos para ser consistentes com elas. Em vez disso, nosso objetivo é ter uma API camelCase baseada em atributos, mas no lado consumidor dos componentes React - nos quais já somos quase consistentes. E class="Button" é claramente mais conveniente do que className="Button" . Na verdade, se a API DOM fosse projetada hoje, provavelmente permitiria que você defina a propriedade .class precisamente porque a restrição de usar class em uma atribuição como essa foi levantada no ES5 - quase dez anos atrás.

A única grande desvantagem restante é o custo de migração. Vamos avaliar isso com cuidado. Mas se estivermos fazendo um monte de mudanças de qualquer maneira, talvez possamos fazer essa também e corrigi-la para sempre. Não estamos pensando nisso de ânimo leve e levamos todas as suas preocupações em consideração.

Nota: isso pode fazer sentido para outros nomes de props React que não correspondem aos nomes de atributos camelCased.

@renatoagds

tem planos para compatibilidade com versões anteriores? Talvez siga o mesmo caminho do React Fiber, adicionando avisos sobre as alterações e dando tempo para atualização de grandes bases de código.

Como observei:

E temos mais de 50 mil componentes no Facebook para nos manter honestos sobre nossa estratégia de migração. Não podemos nos dar ao luxo de reescrever o código do produto, exceto algumas correções direcionadas ou codemods automatizados.

Portanto, definitivamente tentaremos tornar a estratégia de migração o mais suave possível, como sempre fazemos. Se não for suave, não seremos capazes de fazer a mudança sozinhos.

re: className -> class, estou bem com qualquer decisão, posso definitivamente ver a exceção de mudar de classe para novos usuários e um benefício colateral de linhas de código mais curtas. Embora, eles ainda precisariam aprender sobre os outros nomes camelCase.

Portanto, o único inconveniente que resta com a classe é que você não pode escrever isso:

const { class } = props;

Mas acho que com o tempo, esse argumento não é forte o suficiente por si só. React não te força a usar > desestruturar e escrever

const class = props.class;

não é muito mais esforço.

Duas coisas (possivelmente pequenas):

  1. const class = props.class JavaScript não é inválido? Eu não achava que fosse, e em um teste rápido o Chrome não gosta. Além disso, este artigo sugere que não é válido.

  2. Eu pude ver essa mudança sendo uma área de frustração (mais uma vez, potencialmente pequena) para pessoas que escrevem componentes como este: nvm (veja a atualização abaixo)

const { oneProp, twoProp, className, ...rest }  = this.props;

// do stuff with oneProp, twoProp, className

return (
  <div
    someProp={prop}
    anotherProp={anotherProp}
    className={someClassName}
    {...rest}/>
);

Após essa alteração, isso precisaria ser algo como ...

const { oneProp, twoProp, ...rest }  = this.props;

// do stuff with oneProp, twoProp, this.props.className

return (
  <div
    someProp={prop}
    anotherProp={anotherProp}
    {...rest}
    class={someClassName}/>
);

Não é impossível contornar essa mudança, mas é um pouco mais importante ter em mente ao escrever e ler componentes neste estilo.

Atualização :

Deixa pra lá,

const { class: className } = this.props;

faz o truque.

A única grande desvantagem restante é o custo de migração. Vamos avaliar isso com cuidado. Mas se estivermos fazendo um monte de mudanças de qualquer maneira, talvez possamos fazer essa também e corrigi-la para sempre. Não estamos pensando nisso de ânimo leve e levamos todas as suas preocupações em consideração.

Felizmente, isso é facilmente mitigado se alguém estiver usando uma abordagem CSS-in-JS, como Aesthetic. Obrigado pela escrita incrível!

Dica aleatória sobre nomes de atributos, achei o projeto excelente, svg2jsx é ótimo para converter SVGs grandes para usar no React!

@jamesplease Desculpe, minha mente ficou em branco - você está certo. Editado.

@jamesplease você está certo. Isso também aparece frequentemente trabalhando com JSON, para o valor padrão, tão chato!

const { default: defaultVal } = property

Enquanto você está alterando o sistema de eventos, seria muito bom ver algo semelhante à função linkEvent do Inferno para que possamos manipular eventos usando props em componentes funcionais sem ter que criar uma função anônima a cada renderização.

className -> class será uma grande mudança para o ecossistema, vários componentes não mantidos se tornarão incompatíveis e não haverá nada que você possa fazer se não puder corrigi-los. Talvez tenha algum wrapper como StrictMode que desabilite essa alteração para os componentes mais profundos na árvore para fornecer um caminho de migração gradual?

Eu pude ver essa mudança sendo uma área de frustração (mais uma vez, potencialmente pequena) para pessoas que escrevem componentes como este:

const { oneProp, twoProp, className, ...rest }  = this.props;

// do stuff with oneProp, twoProp, className

return (
 <div className={someClassName} {...rest}/>
);

Só não desestrutura.

const { oneProp, twoProp, ...rest }  = this.props;

return (
  <div
    {...rest}
    class={'something ' + rest.class}
  />
);

@gaearon

se o React usa propriedades ou atributos internamente é um detalhe de implementação

Isso parece ser um problema também, honestamente. Os elementos DOM podem se comportar de maneira diferente em alguns casos, dependendo se você está configurando atributos ou propriedades. React não pode saber sobre todas as diferenças, mas usuários de elementos podem saber sobre os elementos que eles usam. O controle explícito sobre propriedades, atributos e eventos permitiria que os autores saíssem dessa situação.

@justinfagnani Se você tiver coisas específicas que gostaria que mudássemos, você se importaria de enviar um problema separado com uma API que você sugere? Isso soa um pouco fora do escopo desta questão.

@sompylasar

className -> class será uma grande mudança para o ecossistema, vários componentes não mantidos se tornarão incompatíveis e não haverá nada que você possa fazer se não puder corrigi-los. Talvez tenha algum wrapper como StrictMode que desabilite essa alteração para os componentes mais profundos na árvore para fornecer um caminho de migração gradual?

Eu concordo – e ainda estamos pesando prós e contras. Nada está finalizado.

Mas, na prática, o problema de componentes não mantidos não é novo - ele surge a cada lançamento principal do React porque algo muda nos principais por definição (não podemos avançar de outra forma e não temos o luxo de manter todo o código legado em o pacote para sempre, ao contrário de, por exemplo, ambientes de servidor). O mesmo problema surgiu quando PropTypes mudou para um pacote separado e acontecerá novamente com a renomeação do ciclo de vida UNSAFE_ . Pacotes não mantidos são bifurcados ou corrigidos. Percebemos que é um grande desperdício de tempo, e é por isso que evitamos fazer mais de uma grande especialização em um ano. Para pessoas que não podem ajudar, normalmente esperar alguns meses antes de mudar para um novo curso é a melhor estratégia, porque os primeiros a adotar abrem o caminho e revivem os pacotes abandonados. Então avançamos todos juntos.

Novamente – eu entendo muito bem sua hesitação, mas isso não é principalmente diferente de outras mudanças que aconteceram no passado, ou que podem acontecer no futuro. Como sempre, colocaremos muito esforço e ênfase em scripts automatizados que você pode executar para converter a maior parte de sua base de código e que você também pode executar em outros pacotes (e enviar PRs para eles - ou fork em seu último estado ).

Independentemente da sua decisão, mais um argumento contra class é a capacidade de pesquisa. Quantos falsos positivos lhe darão a pesquisa por class quando você quiser encontrar componentes que usam classes CSS no código ES6 que usa componentes de classe JS? Sim, você pode procurar por class={ , mas e a desestruturação de props em JSX que são criados como um objeto em JS? (Sou contra o uso pesado de desestruturação de props, mas eles ainda são usados) É claro que precisamos de melhores ferramentas de pesquisa baseadas em AST com reconhecimento de contexto em editores de código, mas por enquanto temos apenas texto e regexp. É claro que os sistemas de tipos podem ajudar a rastrear a passagem de objetos, mas uma grande população não os adotou.

Algo sobre usar uma palavra reservada simplesmente não me agrada, mesmo que não cause nenhum problema agora ; podemos dizer com certeza que rest.class (por exemplo) não será significativo para a linguagem em x anos?

@GeordieP Se funcionar hoje, não pode quebrar amanhã. Esse é o princípio central de como o JavaScript está evoluindo e a razão para muitas de suas idiossincrasias.

@gaearon Justo, então. Se for uma vitória grande o suficiente, eu digo que vá em frente.

@sompylasar Eu costumo pesquisar className= ou className: , parece que ambos funcionariam com class também.

Por favor, livre-se de className , e pelo amor de Deus, htmlFor . Eu não sou um desenvolvedor DOM, geralmente há algo muito errado se eu tiver que acessar métodos DOM nativos. O maior desafio que tenho para integrar as pessoas ao React é a abstração que o JSX faz sobre o DOM e seus estranhos atributos HTML de substituição. Tudo está sendo transpilado, não há motivo para se preocupar com palavras reservadas neste momento. OMI.

Não tenho certeza se isso está adicionando algo à discussão existente, mas parece que deveria haver uma razão melhor para alterar className .

Salvar os alunos iniciantes do React de um nome um pouco não intuitivo é digno de todos terem que atualizar seus projetos e comportamento?

Como alguém que usa a desestruturação liberalmente, ter que lembrar dessa nova exceção à regra é provavelmente um soluço mental maior do que a rara ocasião em que escrevo class em vez de className .

Além disso, os iniciantes ainda não ficariam confusos com a grande quantidade de material (como blogs/repositórios/etc) que usa className atualmente?

Finalmente, como @sompylasar disse, isso prejudica a capacidade de pesquisa na minha base de código.

Talvez este seja um argumento do tipo guias vs espaços, mas não entendo totalmente por que essa alteração é necessária. Parece um grande custo para pouco ganho, a menos que isso faça parte de uma mudança maior em como você deseja modelar a API ao longo do tempo. Dito isso, com certeza usarei o que vocês decidirem 😅.

Um pouco offtop, mas é meio triste que ninguém (até onde eu saiba) teve a ideia de fazer um transformador html/css/svg -> jsx para facilitar migrações para React com tantas mudanças triviais para mapear HTML attrs para Reagir adereços.

@jxub - Eu construí um conversor de HTML para JSX como parte de um hackathon em 2014: https://magic.reactjs.net/htmltojsx.htm. Não tenho certeza se ele lida bem com SVG, no entanto. O projeto hackathon era fazer um script que "ajaxify" um site HTML simples usando React (https://github.com/reactjs/react-magic) e parte disso exigia que eu construísse uma maneira de criar um componente React de um pedaço de HTML, então eu liberei a parte HTML para JSX como uma página independente separada.

Ainda nos preocupamos com o suporte ao IE11, mas é possível que não tentemos suavizar algumas das diferenças existentes no navegador — que é a postura adotada por muitas bibliotecas de interface do usuário modernas.

@gaearon - Quais são alguns exemplos de bibliotecas de interface do usuário modernas que não suavizam as diferenças do navegador? Para mim, essa é uma das principais razões para usar uma biblioteca.

Teoria da conspiração: todas essas notícias de classe/classe são uma coisa brilhante e controversa que todo mundo vai prestar atenção imediatamente e discutir. Ou é para chamar a atenção para o projeto de retrabalho como um todo, ou distrair de algo maior que está acontecendo nas sombras, ou dar uma coisa que pode ser posteriormente retraída enquanto o resto será aceito, como na anedota a seguir:

O grande artista teatral Tyshler, criando esboços de cenários, no canto desenhando um pequeno cachorro verde. E quando um dos comitês de admissão perguntou: "Gosto de tudo, mas onde está esse cachorro?", A artista com um suspiro de arrependimento a engessou.

As verdadeiras razões por trás dessa mudança não são claras, mas elas já dispararam a popularidade deste novo projeto de atualização e o burburinho da comunidade em torno do React.

Seria bom se o suporte a Ouvintes de Eventos Passivos estivesse dentro do escopo do React Fire, que é um recurso importante no celular.

6436

Obrigado por todo o seu trabalho duro nisso, mas por favor reconsidere className -> class .

Todos nós já fomos novatos em React e className não nos impediu de aprender e amar o React.

Lembro que quando estou usando vue com jsx, eles já tinham class not className , discordo se className será alterado para class , pois o React é pioneiro em Virtual DOM , e representam o próprio DOM.

Anexar eventos na raiz do React em vez do documento

@gaearon Isso significa que, em um ambiente de teste, não precisarei anexar elementos ao documento para poder despachar eventos reais do navegador e chamar os manipuladores associados a eles? Ter que fazer isso é muito contra-intuitivo e tenho certeza que tem sido a fonte de muitos desenvolvedores não familiarizados com os internos do React ficarem confusos, perderem muito tempo escrevendo testes e incorrendo em simulação de eventos e práticas de teste ruins.

O que me leva a outra nota, podemos fazer algo sobre react-dom/test-utils ? Estou especialmente interessado na possível remoção de Simulate devido a todos os problemas associados a ele que todos conhecemos e, claro, fazer as alterações necessárias no próprio react-dom para que ele não seja realmente necessário mais. Isso poderia estar no escopo?

/cc @kentcdodds

Eu amo a direção e a visão geral que o React Fire está tomando. Até agora, essas parecem grandes mudanças para se trabalhar.

Adoro as mudanças anunciadas, mas estou cético quanto à mudança className .

O React não força você a usar desestruturação ou usar esse nome de variável específico, e escrever algo como (... trecho de código...) não é muito mais trabalhoso.

Embora não seja muito trabalhoso escrever, na minha experiência atual eu esperaria que fosse _muito_ mais difícil de explicar para outros desenvolvedores (especialmente desenvolvedores de outras linguagens). Por outro lado, em todos os anos em que usamos React em nossa empresa, acho que apenas um ou dois desenvolvedores ficaram confusos com className e aceitaram isso como API do React para definir os nomes das classes em alguns minutos.

(Na minha opinião pessoal, enquanto eu _amo_ destruindo, a sintaxe de renomeação às vezes parece estranha para iniciantes, porque é diferente de renomear em importações que parecem bastante semelhantes e podem ser combinadas com coisas como valores padrão. , mas isso seria uma _grande_ exceção a todos os outros códigos que atualmente escrevemos em nossa empresa. Experiência de outros Pode diferir, é claro, mas essa é a minha opinião sobre o problema 🙃.)

excelente

Também cético sobre a mudança className . É uma das mudanças menores no esquema das coisas, mas está atraindo uma grande parte da discussão de comentários aqui.

Vale a pena gastar tanto capital político em uma mudança, quando há tantas outras coisas boas que estão sendo anunciadas?

Do meu ponto de vista, se você está tomando uma decisão em que parte da justificativa é "e escrever algo como... ...não é _isso_ muito mais esforço.", essa decisão tem que ter um _enorme_ lado positivo, e a mudança className -> class simplesmente não se compara a tudo o que foi anunciado.

este será um grande avanço em 🔥 React Fire

Sobre class v/s className , acho que devemos nos lembrar que JSX ≠ React.

Como JSX é um _DSL_ projetado para se parecer com HTML, é melhor mantê-lo o mais próximo possível do HTML. Concedido é chamado className na API DOM, mas a maioria está usando JSX provavelmente porque eles não querem lidar diretamente com a API DOM.

Se fizer mais sentido para a API do React corresponder de perto com a API DOM, espero que seja ok/possível fazer o mapeamento na transpilação:
<img src="avatar.png" class="profile" />React.createElement("img", { src: "avatar.png", className: "profile" }) .

Seria muito valioso tornar a sintaxe JSX um superconjunto limpo de HTML.

Para adicionar ao que @mhenr18 disse.

Estado atual das coisas:

  • Reagir é inconsistente
  • API é camelCase

Situação proposta:

  • Reagir é inconsistente
  • API é camelCase
  • className -> class

Benefícios perceptíveis:

Se o React fosse de código aberto hoje, parece que os prós de permitir classe (conceitualmente mais próximo do que a maioria das pessoas espera, menos digitação para o prop mais comumente usado) superam as desvantagens (um pouco mais de digitação para interceptá-lo - nesses casos você vai provavelmente só quer o operador de spread de qualquer maneira).

Desvantagens reais:

  • todo o ecossistema que depende de className para de funcionar (enorme esforço de atualização)
  • todo o vasto corpo de livros, tutoriais, exemplos, códigos, postagens, artigos se torna um pouco inválido
  • o único JS válido restante é a digitação adicional : const {class: cls} = props . Todos os outros casos de uso possíveis em JS simples tornam-se inválidos
  • A API do React permanece inconsistente e quebra outras suposições (por que htmlFor não for etc.)

Se eu fosse um gerente de produto, minha reação imediata à mudança seria: o que?

@gaearon Você já deve ter considerado isso, marque PRs com "React Fire" ou uma palavra-chave semelhante.

Os problemas geralmente são marcados corretamente, os PRs às vezes não os têm. Isso ajuda potenciais contribuintes.
Isso vem da minha experiência quando eu estava tentando ler o histórico do git procurando por commits relacionados ao React Fiber e React Reconciler durante todo o desenvolvimento do Fiber. Ajuda aqueles de nós que estão tentando descobrir o que está acontecendo e ver se podemos contribuir de alguma forma.

Eu também acho que renomear className para class causará um grande esforço de migração e problemas para novos desenvolvedores.
O atributo className é tão visível e muito usado que literalmente quebrará todas as bibliotecas que dependem do react.
E isso não é suficiente, a maioria dos tutoriais será quebrada. Um novo dispositivo de copiar e colar de um artigo estará se perguntando "por que isso não está funcionando, diz que className não é um suporte válido".
Então o sênior tem que ajudar e nós não ganhamos nada, porque ainda temos que explicar porque não funciona como você esperaria.
E de verdade, explicar que você tem que usar className para definir classes no componente leva menos de um minuto e é de fácil compreensão. Explicar por que eles mudaram de className para class para cada desenvolvedor leva muito mais tempo e resulta em mais frustração.

Todos os esforços necessários para uma única palavra.
Isso não mudará nada na maneira como o react se comporta.
Não irá impulsionar o desenvolvimento de react-dom.
Não aumentará a produtividade dos desenvolvedores que trabalham mais de uma semana com o react.
Vai quebrar tudo.

Por favor, pense sobre isso, realmente vale a pena?

Eu tenho usado babel-plugin-react-html-attrs por anos e tem me servido bem, não acho que renomear className para class seja uma boa ideia. É melhor alcançado por um plugin como o que mencionei.

Não havia um plugin Babel para lidar com toda a situação " class v className " / " for v htmlFor "?

Espero que seja possível oferecer suporte a atributos html como estão, mantendo a compatibilidade com versões anteriores com as decisões de nomenclatura já feitas.

O fato de já existirem plugins babel para fazer a conversão, talvez seja uma evidência de que deveria ser possível suportá-lo no próprio transpilador JSX principal. Mas torná-lo uma especificação oficial tornaria as coisas muito mais fáceis e confiáveis ​​para todos.

Eu não estou ciente dos internos do React, então não posso dizer muito sobre a real viabilidade. Apenas expressando como eu acho que "deveria ser" em termos de facilidade de uso.

Por favor, reconsidere className vs class . Como foi dito acima, o ganho é quase inexistente, mas há desvantagens reais.

Uma delas é que, para nós, usando Haxe como uma linguagem para escrever aplicativos react, isso não seria apenas uma mudança importante, mas simplesmente nos impediria de escrever _qualquer_ aplicativo react.

class é uma palavra-chave reservada na maioria das linguagens de programação, e simplesmente não poderíamos mais manipular essa prop, tornando a aplicação de reação quase impossível (boa sorte criando uma real sem manipular classes). O mesmo vale para htmlFor vs for , infelizmente (este é realmente feio, mas sou grato por existir).

Ah, a propósito, pesquisabilidade... Imagine que você pesquise no Google por "classe React", você obterá sinais mistos: componentes de classe React, atributo de classe React. Você pesquisa no Google por "React className", você obterá documentação desatualizada (pessoas mencionadas acima, a enorme quantidade de trabalho de atualização gerado por essa alteração, além de atualizações de código).

O objetivo deste projeto é gerar mais trabalho para a comunidade e mais ruído e sinais mistos para a Internet? Espero que não.

Sim, o ecossistema da Web e JavaScript luta para manter a retrocompatibilidade com erros estúpidos do passado, mas essa busca pela retrocompatibilidade foi o que permitiu que ele crescesse em tal escala sem grande fragmentação.

Eu entendo que não há progresso sem mudança, e eu mesmo adotei o lema do FB inicial de quebrar as coisas para se mover rápido (também ter um plano de como remontá-las com antecedência).

Se você está sendo tão persistente que essa mudança é realmente necessária, apenas diga o verdadeiro motivo da mudança. Não pode ser a coisa "difícil de aprender", parece muito superficial para a poderosa equipe React Core. Você definitivamente deve ter algo em mente.

@sompylasar Eu costumo procurar className= ou className:, parece que ambos funcionariam com class também.

Além disso, boa sorte fazendo isso diretamente no github =/

Li todos os comentários aqui. Estou bem com as alterações, mas não tenho certeza sobre class . A principal razão é porque não funcionará com planos para JSX 2.0. sobre notação de atalho (como temos agora em objetos).
Tudo o resto parece ser melhorias muito agradáveis.
Aguardando a decisão final :) Obrigado por seus esforços incríveis pessoal!

Em um de seus comentários, você mencionou “se funciona hoje, deve funcionar amanhã”. Tenha isso em mente antes de perguntar;).

Eu mantenho uma biblioteca de interface do usuário chamada RMWC https://jamesmfriedman.github.io/rmwc/ que tem como alvo todas as versões do React até 15.4. Consegui manter uma superfície de API unificada, mas alterar className para class, onChange para onInput e revisar o sistema de eventos tornará isso quase impossível de continuar.

Existe alguma possibilidade de uma camada “compat” que possa traduzir algumas dessas coisas sob o capô? Então eu posso escrever em qualquer versão que reaja ao fogo, mas continue a rodar em um tempo de execução menor.

Caso contrário, espero que meu código estranho fique ainda mais estranho. 👀

se className realmente tiver que mudar para class , também altere htmlFor para for .
desde class e for originalmente inválidos quando desestruturamos props .

Se o React tem sua própria API que normaliza muitos nomes de atributos para fazer uma API consistente, então certamente className é perfeito para isso. Um aprendizado idiomático extra em cima dos idiomas camelCase, além do fato de mapear para o nome da propriedade DOM (como alguns dos outros atributos JSX) certamente é bom em comparação a ter que desestruturar como um caso especial toda vez que você usa um objeto de adereços com ele ligado.

Eu sinto que, até agora, você ouviu muitas opiniões vocais contra o status quo (“por que não podemos ter aula?”) enquanto todos que estavam felizes em usá-lo ficaram quietos; de acordo com o velho ditado de que as pessoas são muito mais propensas a dar críticas negativas do que positivas. Pessoalmente, acho que uma pequena curva de aprendizado em cima de muitas outras é muito melhor do que uma caixa especial desse suporte toda vez que ele aparece.

Acho que gostaria de ver um pouco mais de democracia em torno disso - acho que essa mudança muito específica pode ser feita por comitê (foi essencialmente um pseudocomitê que levou você a considerar essa mudança) - e estou feliz por estar o lado perdedor. Só para que isso afete o mínimo de pessoas no dia a dia.

Ps todo o resto parece ótimo, especialmente as coisas do evento 👌🏻

aguardando novas atualizações

@gaearon Vale a pena considerar que seu próprio exemplo:

const { oneProp, twoProp, ...rest }  = this.props;

return (
  <div class={'something ' + rest.class} {...rest}/>
);

contém um bug e não funcionaria como você esperava? Pode não ser tão simples quanto "Só não desestruturar."

eu sou o único que não estava tão preocupado com a classe sendo className? Se você me perguntasse quais problemas reagem se isso nunca passaria pela minha cabeça.

Ainda assim, as atualizações são brindes e eu amo brindes.

eu sou o único que não estava tão preocupado com a classe sendo className?

Não estou nem um pouco preocupado com a classe. Os bugs sutis com o IE11 serão mais engraçados (e ainda estou mais do que bem com essas mudanças)

Seria bom se o suporte a Ouvintes de Eventos Passivos estivesse dentro do escopo do React Fire, que é um recurso importante no celular. #6436

Eu concordo. Está definitivamente no escopo deste trabalho.

Ei @gaearon - em primeiro lugar obrigado.

Você já pensou em fazer uma pesquisa para coletar informações sobre como as pessoas estão usando o react e quais APIs estão sendo usadas e o que é confuso?

Embora o React seja de longe a minha pilha de desenvolvimento de frontend favorita, acho que existem algumas armas de fogo ao aprender e usá-lo pela primeira vez. Não quero apenas expor o que as pessoas que ensinei acharam pessoalmente confuso.

Achei útil em projetos nos quais estive envolvido pessoalmente (Node, Bluebird etc).


Em termos do que eu pessoalmente gostaria de ver no núcleo: eu adoraria um suporte melhor e mais simples de injeção de dependência não global, manipulação de eventos melhor e mais consistente (que você já está discutindo).

Você já pensou em fazer uma pesquisa para coletar informações sobre como as pessoas estão usando react > e quais APIs estão sendo usadas e o que é confuso?

Eu acho que react-native tem um canny.io eu não sabia que react não tem

Eu mantenho uma biblioteca de interface do usuário chamada RMWC https://jamesmfriedman.github.io/rmwc/ que tem como alvo todas as versões do React até 15.4. Consegui manter uma superfície de API unificada, mas alterar className para class, onChange para onInput e revisar o sistema de eventos tornará isso quase impossível de continuar.

Existe alguma possibilidade de uma camada “compat” que possa traduzir algumas dessas coisas sob o capô? Então eu posso escrever em qualquer versão que reaja ao fogo, mas continue a rodar em um tempo de execução menor.

Eu simpatizo com suas preocupações (eu também escrevi meu quinhão de bibliotecas). No entanto, uma vez que há tantas compensações em mudar qualquer coisa, tendemos a errar do lado de se esforçar para ajudar as pessoas a atualizar em vez de ajudar as pessoas a suportar várias versões. Isso não significa que não fazemos isso (liberamos um polyfill para autores de bibliotecas para alterações no ciclo de vida na versão 16.3), mas não otimizamos para este caso de uso.

Minha sugestão é cortar um novo curso quando cortamos um novo curso se algo for incompatível. As pessoas podem continuar usando as versões principais antigas de sua biblioteca, se quiserem. Eu sei que é mais difícil manter, especialmente se você continuar desenvolvendo, mas é questionável se uma única base de código hacky é melhor do que duas bases de código divergentes, mas consistentes.

@jamesmfriedman deve ser possível (e não muito complicado) atualizar (automaticamente) com um codemod) para a nova API e depois (como parte do processo de compilação) transformar (novamente com um codemod) para a API antiga. Em seguida, envie os dois pacotes e exija-os dinamicamente com base na versão do React.

Isso é um pouco trabalhoso, mas pode ser feito uma vez (como um plug-in do webpack ou script de instalação do npm, por exemplo?) e não deve ser difícil. Eu diria que é o tipo de coisa a ser lançada uma vez e usada em todas as bibliotecas.

Como uma camada de compatibilidade de tempo de compilação especificamente para bibliotecas.

Eu apoio a eliminação de htmlFor for for.

Você acha que uma versão de ponte que suporte className e class seria uma boa ideia? Isso permitiria que os desenvolvedores usassem código React mais antigo de terceiros, enquanto seu código original atual pode ser voltado para o futuro. Depois que o terceiro for atualizado, é tão fácil quanto descartar o pacote de ponte para ter um React DOM totalmente otimizado.

A API React permanece inconsistente e quebra outras suposições (por que htmlFor não para etc.)

Acho que você perdeu a última frase quando eu disse que for também deveria mudar. Então acho que seremos totalmente consistentes com “nomes de atributos em caixa de camelo”, exceto um ou dois atributos SVG raros. O que também podemos mudar.

Não havia um plugin Babel para lidar com toda a situação “class v className” / “for v htmlFor”?

Eu vejo algumas menções sobre isso, então eu gostaria de esclarecer. Um plug-in Babel não é um ótimo lugar para fazer essa conversão porque não funciona para casos como

const props = {
   class: "foo"
}
<div {...props} />

Também não faz sentido você passar class mas receber className em props do componente. Ou, se o plug-in segmentar apenas os elementos da plataforma, seria estranho que substituir button por um Button alterasse o que o prop class compila.

Usar o plugin Babel para isso apenas obscurece a semântica do código que você está escrevendo e leva a mais confusão. Na minha opinião, é uma solução pior do que permitir apenas className ou class .

Curiosidade: era assim que funcionava uma versão muito antiga do compilador JSX. Esse comportamento foi removido devido ao quão confuso ele é.

Mudanças impressionantes. . .

Incrível! Obrigado a todos os colaboradores por trabalharem para trazer atualizações tão interessantes.
Eu não fazia ideia que className > class era um escândalo tão grande. Pessoalmente já me acostumei.

O tamanho reduzido do pacote e o sistema de eventos atualizado parecem realmente promissores. Super empolgado!

Estou realmente ansioso para separar os polyfills do sistema de eventos como pacotes separados.
Mas se className > class é muito radical, você sabe, o React tem um impacto muito amplo.
Isso levará ao imprevisto de muitos sistemas?

Descartar um terço do React DOM seria bom.

Será ótimo usar o React no desenvolvimento de aplicativos da web.

Também seria bom para o namespace reagir a props específicos como key e ref . por exemplo

<Foo @key="foo" @ref={callback} prop="hi" />

isso foi discutido aqui - https://github.com/facebook/jsx/issues/66

@elado Embora possa ser algo que queremos fazer no futuro, acho que está fora do escopo porque afeta a API não específica do DOM.

Embora seja emocionante, especialmente a redução no tamanho do pacote, que é sempre bem-vinda. Minha preocupação é que o pessoal do Facebook esteja subestimando a inércia, a dor e a fragmentação que as mudanças de API podem causar ao ecossistema e à comunidade.

É verdade que eles têm um grande número de componentes no FB para se preocupar, mas a vantagem que eles obtiveram, e eu suponho aqui, é sua dependência mínima de bibliotecas externas de código aberto, já que eles provavelmente construíram a maioria de seus componentes internamente. Para as outras pessoas que usam muitas bibliotecas de código aberto, realmente foi um grande esforço, espera e frustração para obter Proptypes de muitas bibliotecas (e falo de uma experiência real de atualização de uma grande base de código de reação). Mover-se rápido e quebrar as coisas pode não ser aplicável para as pessoas que desejam construir negócios estáveis ​​com recursos limitados.

Eu realmente gosto de reagir, a API é simples e pessoalmente não demorei muito para aprender e ajustar a sua sintaxe. Assim, eu realmente peço ao mantenedor que avalie cuidadosamente os prós/contras de qualquer mudança de ruptura no ecossistema e pense pragmaticamente se a mudança justificar forçar todo o ecossistema a reescrever.

Fora isso, eu realmente aprecio o esforço de construir, manter e atualizar o React, e a paixão dos engenheiros por trás dele :)

Essas futuras {...atualizações} são 🔥

className -> class : Não acho que seja uma situação rara quando o atributo class é definido fora da declaração JSX/object. Em tais situações teremos que usar nomenclaturas diferentes para a mesma coisa, gerando inconsistências, aumentando a complexidade do código e a carga cognitiva.
A alteração sugerida não removerá a incompatibilidade de nome de atributo/prop de nossas bases de código - ela existirá em algum lugar devido às limitações de sintaxe ou ao trabalhar com DOM nativo. Foi bom termos "padronizado" (e bem estabelecido neste momento) a solução para esse problema de nomenclatura.
Atualmente className pode ser usado de forma consistente em todos os lugares, sempre se referindo à mesma coisa - mesmo quando se trabalha com DOM nativo. Na verdade o react pode ser literalmente o único lugar onde seremos forçados a usar class para nos referirmos ao atributo class.
className parecia bastante desnecessário e um pouco confuso desde o início, mas acabou sendo bastante prático depois e relativamente fácil de se acostumar.

Eu também me livraria do objeto extra { __html } por dangerouslySetInnerHTML , pois parece realmente desnecessário, mas pode não valer a pena os problemas relacionados à migração (e talvez não relacionados a esse problema).

Enquanto as outras mudanças geram muito menos emoções, elas são muito mais interessantes e importantes, então obrigado equipe do fb pelo esforço.

Quanto mais alterações importantes, mais tempo levará para atualizar os aplicativos reais do usuário. Pessoalmente, já estou muito atrás do último grande React (o que me entristece), porque as versões anteriores do React quebraram coisas que exigem bibliotecas das quais dependo para atualizar, o que introduz atraso.

Idealmente, eu gostaria de estar no cenário que:

  • A biblioteca React downstream reescreve o código na nova versão, introduzindo um bug para o meu caso de uso
  • React adiciona um novo recurso legal / redução de pacote
  • A versão antiga da biblioteca permanece utilizável no novo React
  • Yay, eu posso usar o novo recurso logo após o lançamento do React e apenas esperar a biblioteca corrigir o bug

Na prática é mais como:

  • Biblioteca reescreve código, introduzindo bug
  • React lança nova mudança de última hora
  • Biblioteca antiga não funciona mais
  • Nova biblioteca eventualmente atualiza
  • O bug ainda pode estar presente
  • Estou preso no React desatualizado em vez de (para citar Ken Wheeler) "a nova gostosura" há muito tempo.
  • Eu me sinto triste :(

De uma 'perspectiva de código de envio', cada atualização importante torna-se uma enorme dívida técnica irritante que envolve a atualização de todas as dependências, o reteste de tudo e a caça de novos bugs para ver se há uma solução alternativa. A menos que haja uma vulnerabilidade crítica ou seja realmente impraticável fazer algo (e essa barra é alta), ela será despriorizada.

Infelizmente, apesar de ter perdido o paradigma 0.x e apesar de tentar ser uma biblioteca web principal, o React ainda está produzindo números de versão, o que significa muito tempo gasto correndo para ficar parado.

Basicamente, o que estou dizendo é, por favor, tente planejar uma API que permita que grandes mudanças futuras não sejam interrompidas.

(Também a coisa do IE11 é triste porque você está descontinuando um navegador que não é EOL - última versão 52 dias atrás. Acho que a equipe do React descobrirá que isso apenas empurra o trabalho para a equipe do Facebook e todas as equipes externas e internas da biblioteca para mitigá-lo em vez de).

@urugator

Eu também me livraria do objeto extra { __html } para perigosamenteSetInnerHTML, pois parece realmente desnecessário

Isso é intencionalmente projetado para ser explícito e difícil de usar acidentalmente. Se ele for removido, quaisquer dados não higienizados podem ser acidentalmente passados ​​para perigosamenteSetInnerHTML.

@philipwhiuk

Basicamente, o que estou dizendo é, por favor, tente planejar uma API que permita que grandes mudanças futuras não sejam interrompidas.

Mudanças radicais são necessárias para melhorar a tecnologia, e o React faz isso de forma responsável com lotes infrequentes de mudanças importantes. Sem mudanças importantes, como remover componentWillReceieveProps, não teríamos grandes coisas como React Suspense, e software na comunidade seria mais difícil de manter com APIs antigas permanecendo para sempre. Se você atualizar uma versão principal de cada vez, deve ficar bem.

Além disso, a coisa do IE11 é triste porque você está depreciando um navegador que não é EOL - última versão 52 dias atrás.

Ninguém está depreciando o IE 11. A versão atual do React realmente requer polyfills para alguns recursos no IE 11, então as mudanças sugeridas provavelmente teriam o mesmo efeito no desenvolvimento do IE 11. https://reactjs.org/docs/javascript-environment-requirements.html

Eu também me livraria do objeto extra { __html } para perigosamenteSetInnerHTML, pois parece realmente desnecessário

@urugator - Se vale a pena, internamente no Facebook o uso mais comum de __html é inserir HTML renderizado pelo servidor em uma árvore de componentes React. Para esse caso de uso, construímos os objetos __html do lado do servidor e temos regras de lint contra fazê-lo no lado do cliente. Do lado do servidor, temos métodos que serializam o XHP para objetos com propriedades __html . Isso garante que não introduzimos nenhuma falha de segurança em nenhum lugar, pois o XHP é muito semelhante ao JSX (na verdade, foi a principal inspiração para o JSX) e também possui proteção XSS.

Essencialmente, os objetos __html marcam uma string de HTML que sabemos que foi higienizada em algum lugar e é segura para inserir diretamente no DOM. Uma string bruta é mais difícil de manusear - Como você pode saber se ela foi higienizada ou se alguém retornou acidentalmente alguma entrada bruta do usuário (e, portanto, introduziu um buraco XSS)?

Então, sim, é intencionalmente difícil de usar, porque não deve haver muitos casos de uso na maioria dos aplicativos, e os casos de uso devem ser razoavelmente contidos. Geralmente você não deve construir o objeto __html diretamente em seu componente React, mas sim ter alguma função que o retorne (veja como os documentos usam uma função createMarkup : https://reactjs. org/docs/dom-elements.html#dangerouslysetinnerhtml)

Minha preocupação é que o pessoal do Facebook esteja subestimando a inércia, a dor e a fragmentação que as mudanças de API podem causar ao ecossistema e à comunidade.

Obrigado por trazer isso à tona. Eu entendo totalmente de onde você está vindo. Mas eu gostaria de salientar que a maioria das pessoas na equipe do React tem usado o React fora do Facebook antes de serem contratados – geralmente em grandes aplicativos. Então, acho que isso nos ajuda a ter empatia com os tipos de problemas que afetam nossos usuários de código aberto. Eu usei o React por dois anos e lembro muito bem da fragmentação causada por, por exemplo, a troca de contexto pai/proprietário. A chave era ter uma boa estratégia de migração — e o mesmo se aplica a todas as mudanças acima.

É verdade que eles têm um grande número de componentes no FB para se preocupar, mas a vantagem que eles obtiveram, e eu suponho aqui, é sua dependência mínima de bibliotecas externas de código aberto, já que eles provavelmente construíram a maioria de seus componentes internamente.

Isso tem sido historicamente verdade para o lado do desenvolvimento do produto. No entanto, desde que o Yarn foi criado e integrado ao nosso repositório da Web, vimos um número crescente de componentes de terceiros usados ​​em páginas de ferramentas internas — que por si só têm uma área de superfície muito maior do que os produtos de consumo do Facebook. Então vamos precisar de uma estratégia de migração gradual em pacotes de terceiros também.

Ao contrário de muitas outras empresas, usamos a mesma versão do React em toda a base de código. Portanto, também temos desafios únicos (por exemplo, não podemos apenas "esperar" a atualização de alguns produtos). Isso certamente nos pressionará ainda mais para ter uma boa estratégia de migração e servir como teste de estresse.

Para as outras pessoas que usam muitas bibliotecas de código aberto, realmente foi um grande esforço, espera e frustração para obter Proptypes de muitas bibliotecas (e falo de uma experiência real de atualização de uma grande base de código de reação). Mover-se rápido e quebrar as coisas pode não ser aplicável para as pessoas que desejam construir negócios estáveis ​​com recursos limitados.

Caso você esteja curioso, ainda temos código como

React.PropTypes = require('prop-types')
React.createClass = require('create-react-class')

em nossa base de código porque também não podemos migrar totalmente para uma "tábua limpa". Mas as pessoas que estão começando com o React hoje, assim como as partes mais modernas de nossa base de código, não precisam carregar esse peso. É assim que pensamos sobre isso - queremos escolher melhores padrões para novos usuários do React, mas ter uma boa história de migração para nós e para todos os outros, mesmo que algumas partes possam ser hackeadas.

Eu posso não ter comunicado isso de forma clara o suficiente, então peço desculpas. Qualquer grande mudança precisará de uma estratégia de migração sofisticada e bem executada que leve em consideração que bibliotecas de terceiros levarão muito tempo para atualizar, versões diferentes podem precisar coexistir etc. Por exemplo, com class o plano não é apenas mudá-lo da noite para o dia. Se quisermos fazer isso, queremos ser inteligentes sobre como implementá-lo - possivelmente com um período de carência em que permitimos ambos, ou um auxiliar para facilitar a execução e, em seguida, gradualmente eliminando o nome antigo . Ainda não tenho uma estratégia específica, mas está claro que a mudança é simplesmente inviável sem uma boa estratégia – tanto para nós quanto para você. Isso é algo que levamos muito a sério.

(Também a coisa do IE11 é triste porque você está descontinuando um navegador que não é EOL - última versão 52 dias atrás. Acho que a equipe do React descobrirá que isso apenas empurra o trabalho para a equipe do Facebook e todas as equipes externas e internas da biblioteca para mitigá-lo em vez de).

Não entendo a que você se refere. Eu não disse em nenhum lugar que o IE11 estava ficando "obsoleto".

Meu post diz apenas que podemos exigir mais polyfills do que agora para navegadores como o IE11. O React requer alguns polyfills no IE11. Não estou dizendo que queremos quebrá-lo - ele ainda tem muitos usuários - mas que você precisará incluir mais polyfills se quiser que funcione. Isso me parece inteiramente justo.

Além disso, não podemos "empurrar o trabalho" para outras equipes no Facebook. Se quebrarmos algo, cabe a nós consertá-lo. É por isso que nos preocupamos tanto com as estratégias de migração — normalmente temos que executá-las nós mesmos.

Re: o resto do seu comentário - nós absolutamente não fazemos mudanças significativas por causa disso. Na verdade, estamos nos esforçando muito para evitar mudanças que quebram. Existem muitas partes do React que são complicadas e difíceis de manter, mas as mantemos pelo único motivo de estarmos tentando oferecer suporte a APIs legadas, mesmo que tenham sido explicitamente marcadas como instáveis. No entanto, em algum momento, o peso dos problemas se acumula e precisamos limpar a lousa para seguir em frente e corrigi-los. Os problemas no meu post OP são exatamente esses tipos de problemas. Eles não valeriam a pena fazer uma mudança de ruptura sozinhos. Mas combinados, achamos que valem o esforço.

Não entendo por que as pessoas são tão negativas quanto a isso. Apenas não atualize até que suas dependências o façam?

O problema da palavra-chave para class vs className e for vs htmlFor não é algo que o compilador jsx possa manipular para substituir as palavras reservadas?

Eu realmente só ficaria preocupado se as mudanças fossem grandes o suficiente para que os resultados da pesquisa fornecessem respostas obsoletas ... Como a dor angular 2+ introduzida ao pesquisar "angular -angularjs -angular1.x" etc.

Fora isso, congratulo-me com todas as mudanças!!!

@gaearon

Você disse

"Podemos precisar descartar a compatibilidade com alguns navegadores mais antigos"

Foi a parte de compatibilidade de queda que tive um problema, não a seguinte parte do polyfill. Voltar para a idade das trevas era minha preocupação.

Em relação ao processo. Não é esse tipo de 'questão' para o qual o processo RFC foi projetado?

Foi a parte de compatibilidade de queda que tive um problema, não a seguinte parte do polyfill. Voltar para a idade das trevas era minha preocupação.

Eu estava falando sobre o IE10 e anteriores. Observei especificamente que queremos continuar a oferecer suporte ao IE11 - acho que representa cerca de 3% do nosso tráfego, o que é muito mais do que o limite de 1% em que consideramos muito antigo.

Em relação ao processo. Não é esse tipo de 'questão' para o qual o processo RFC foi projetado?

Postaremos RFCs quando as coisas estiverem mais detalhadas. Muito disso requer exploração, experimentação e testes reais para determinar o que podemos e não podemos fazer e quais estratégias de migração podemos usar. No momento, não temos detalhes suficientes para começar a pensar em RFCs (que devem incluir uma estratégia de migração abrangente).

Ok, obrigado pelo esclarecimento!

@gaearon

É plausível que nos livremos completamente dos eventos sintéticos.

Como isso funcionaria com event.currentTarget apontando para o elemento no qual o ouvinte de eventos está anexado, que no caso nativo sempre significa document - ou a raiz do React quando o React muda para isso?

React não é apenas definir propriedades

(...)

Meu ponto aqui é que se o React usa propriedades ou atributos internamente é um detalhe de implementação

Por que isso é um detalhe de implementação quando pode influenciar o que acontece no DOM? A menos que se refira apenas a propriedades que de alguma forma são refletidas em atributos (e vice-versa) como class / className .

Eu sinto que a confusão em torno do tratamento de class / className está relacionada ao fato de que se o React usa uma propriedade ou um atributo é considerado um detalhe de implementação. Eu tenho um background em Angular e quando comecei a usar o React foi a maior pegadinha para mim - em Angular a separação entre atributos, propriedades e manipuladores de eventos é clara diretamente da sintaxe e fiquei confuso se as props nos elementos DOM são definidas pelo React como propriedades ou atributos.

Como isso funcionaria com event.currentTarget apontando para o elemento no qual o ouvinte de eventos está anexado, que no caso nativo sempre significa documento - ou a raiz do React quando o React muda para isso?

Eu não sei ainda. :-) Veremos o que podemos fazer. É inteiramente possível que algumas dessas coisas não funcionem ou saiam de forma diferente. Este plano é apenas um esboço das coisas que planejamos analisar e a visão unificadora para elas.

Por que isso é um detalhe de implementação quando pode influenciar o que acontece no DOM? A menos que se refira apenas a propriedades que de alguma forma são refletidas em atributos (e vice-versa) como class/className.

Para a maioria deles, não há diferença observável da perspectiva do usuário sobre qual usar. Eu acho que a maioria deles são refletidos (embora talvez eu esteja errado).

Eu tenho um histórico em Angular e quando comecei a usar o React, a maior pegadinha para mim - em Angular, a separação entre atributos, propriedades e manipuladores de eventos é clara diretamente da sintaxe e fiquei confuso se as props nos elementos DOM são definidas pelo React como propriedades ou atributos.

Eu aprecio sua perspectiva. No entanto, na prática, essa diferença geralmente é irrelevante para a maioria dos elementos DOM e é discutível que aprender os detalhes de qual usar, e sempre ter que pensar sobre isso, é realmente valioso para o desenvolvimento diário de produtos. Eu acho que o grau em que as pessoas os confundem fala do fato de que não é realmente muito relevante para eles.

( casos em que se torna muito mais relevante, como com elementos personalizados. Mas mesmo assim, suportar ambos igualmente é tão confuso porque você precisa escolher qual usar. Isso foi debatido em outros lugares, então eu gostaria de evitar pular neste debate novamente - temos propostas de pessoas como @robdodson e vamos analisá-las.)

@Daniel15
Sem as políticas mencionadas (que eu acho que não são mencionadas em nenhum outro lugar), o wrapper de objeto extra não o torna mais seguro de forma alguma.
Acredito que o usuário esteja suficientemente avisado sobre o uso perigoso via dangerouslySetInnerHTML . Esse é o ponto em que o usuário é forçado a verificar os documentos, considerar as implicações e tomar a decisão.
A necessidade de envolver a string (possivelmente não higienizada) em um objeto/função, não o fará reconsiderar ou higienizar o valor encapsulado.
Se funcionasse assim, talvez { __html } não seja complicado o suficiente e [{ _html: { __html }] o tornaria ainda mais seguro - quantas vezes temos que afirmar que algo é perigoso para torná-lo seguro ?

Com o insight que você forneceu, eu entendo o raciocínio, mas acho que atualmente não se aplica a ninguém fora do facebook, porque não temos a menor ideia sobre a regra " { __html } representa html higienizado".
Sempre pensei que fosse apenas mais uma obstrução na API. Obrigado por tirar um tempo e lançar alguma luz sobre isso, faz mais sentido agora.

Não se trata apenas de torná-lo mais complexo, trata-se de impedir que dados não higienizados sejam usados ​​acidentalmente.

Eu adoro a maneira como reagir é tão opinativo pela comunidade. Parabéns por vocês ouvirem tudo e tirarem o melhor proveito disso.

Eu amo como todo mundo acha que as mudanças que estão chegando aqui ou que vieram para o React nas últimas versões foram 'quebrantes'. Essas pessoas claramente não experimentaram o Angular 2 > 3 > 4 vezes.

Eu amo as mudanças. Pessoalmente eu não me importo com className e desestruturar class pode se tornar um aborrecimento. Mas eu adoraria ver o que vocês vão inventar.

Eu gostaria de pedir para manter esta discussão no tópico. Se você acha que a contaminação de HTML perigoso é útil ou não, é interessante, mas não está relacionado ao problema.

eu amo reagir

Esta é uma oportunidade perfeita para ajudar os desenvolvedores novos a reagir a se sentirem mais bem-vindos. Estou muito feliz por isso estar acontecendo.

Apenas deixar as pessoas usarem a classe não tem efeitos negativos, exceto que não funciona com a desestruturação e o custo de migração.

@gaearon Jogando 2c, mas esses dois negativos parecem tão grandes ou maiores que o negativo atual (um custo pequeno de aprendizado de classe => className vs sempre evitar a desestruturação + custo de migração no nível do ecossistema).

Reaja :heart:

ecoando @natew acima:

@gaearon Jogando 2c, mas esses dois negativos parecem tão grandes ou maiores que o negativo atual (um custo pequeno de aprendizado de classe => className vs sempre evitar a desestruturação + custo de migração no nível do ecossistema).

De qualquer forma, qual é a motivação por trás da mudança de className para class ?
Tanto quanto eu posso recolher o seu comentário se resume a dois argumentos, (por favor, corrija-me se estiver errado):

conceitualmente mais próximo do que a maioria das pessoas espera

Ok, mas adicionar Name é o menor dos obstáculos. Aprender a usar className foi a parte mais simples de aprender React. É uma pequena peculiaridade que não tem desvantagens - na verdade, resolve um problema com quatro caracteres. E tem muito menos sobrecarga cognitiva do que qualquer uma das alternativas de desestruturação fornecidas.
Imagine ensinar alguém a estilizar seu primeiro componente React com

function Button({ color, ...rest }) {
  const buttonClass = rest.class +  ' Button-' + color;
  return <button {...rest} class={buttonClass} />
}

Minha cabeça de noob teria explodido.
Acho que ao interagir com uma API as pessoas esperam que a API forneça soluções. ClassName é uma solução integrada. A classe é um problema embutido.

menos digitação

Bruh, são quatro caracteres 8^) . Além disso, mesmo se desestruturarmos class com muito menos frequência do que usamos atualmente className , é muito mais digitação quando o fazemos. Então, terei digitado 4 caracteres a menos 12 vezes, mas adicionado 50 caracteres a mais cada vez que desestruturar class ? Isso é simplesmente bobo.

Existe outra razão convincente para esta mudança que eu perdi?
A motivação é algum tipo de preocupação com a conformidade com os atributos/propriedades do DOM?
Isso me parece um argumento acadêmico demais. A maioria das pessoas não está muito ciente desses detalhes de implementação e eu não acho que eles precisem estar.

Será que, se lançado hoje, o React permitiria class em vez de mudar para className?
Acho que isso é irrelevante.
O React não era open source hoje e se fosse/seria open source daqui a um ano, um conjunto diferente de decisões poderia ser feito naquele momento.
Às vezes é melhor manter a consistência do que tentar eliminar cada ruga.

E se o React estivesse usando class desde o início, teríamos nos acostumado a desestruturar a classe e reatribuí-la a className, mas quem viesse com um PR para mudar de classe _para_ className seria saudado como um salvador.

Por fim, só quero dizer que não esperava ficar tão nervoso com isso, então peço desculpas se algo parecer rude, ofensivo ou acusatório. Sou grato por todo o trabalho que você faz no React e por todo o conhecimento que passa no Twitter - usei seus tweets para defender algumas respostas que dei em entrevistas.

Eu rezo para dan.church que você mude de ideia.

Estou muito feliz que o react pode ser continuamente atualizado. Como desenvolvedor do uso do react, eu não quero vê-lo sendo ultrapassado pelo vue. Mas o processo de className-> class deve ser doloroso.

Eu não sou contra a renomeação className -> class para copiar e colar, mas não há uma motivação clara para isso a partir de agora. className existe no DOM enquanto existem nomes de props reservados que surgem do nada como htmlFor . Eu sinto que eles devem ser priorizados quando se trata de renomear e isso provavelmente é menos abrangente de uma mudança que também pode servir como teste.

@sonhanguyen htmlFor também é o nome oficial da API da web: https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor

@allan2coder em vez de envolvê-lo em uma matriz, envolva-o em <React.Fragment> ou <> .

@allan2coder Além disso, vamos manter este tópico no tópico, você pode fazer perguntas preenchendo um problema separado, se desejar.

Eu gostaria de chamar a atenção para patch-package que é um pacote que torna bastante fácil corrigir suas dependências (por exemplo, para fazê-las parar de usar APIs React não suportadas). É certo que isso é mais útil para o código do aplicativo do que para o código da biblioteca, mas acho que deve ajudar a resolver algumas das preocupações de @philipwhiuk .

Estou ansioso。

  • Migre de onChange para onInput e não o preencha com polyfill para componentes não controlados.

Para as palavras acima, estou curioso para saber se o evento onChange será usado próximo ao evento nativo ou não será usado no futuro?

@MuYunyun

Com base no texto, eles não planejam manter o comportamento atual do onChange. Não faria muito sentido. Reagir como outras bibliotecas modernas não será uma camada de compatibilidade do navegador, nem deveria ser.

O onChange atual emula onput + alguns outros casos. Não faz sentido, considerando que um evento de mudança já existe no DOM e não tem a mesma semântica: https://developer.mozilla.org/en-US/docs/Web/Events/change

@jxub

Um pouco offtop, mas é meio triste que ninguém (até onde eu saiba) teve a ideia de fazer um transformador html/css/svg -> jsx para facilitar migrações para React com tantas mudanças triviais para mapear HTML attrs para Reagir adereços. Tantas horas de trabalho desperdiçadas realizando principalmente localizar e substituir :(

Não conheço outros editores, mas o IntelliJ IDEA (e WebStorm, PhpStorm etc.) faz essa transformação, quando você cola um código HTML no JS.

Um pouco offtop, mas é meio triste que ninguém (até onde eu saiba) teve a ideia de fazer um transformador html/css/svg -> jsx para facilitar migrações para React com tantas mudanças triviais para mapear HTML attrs para Reagir adereços. Tantas horas de trabalho desperdiçadas realizando principalmente localizar e substituir :(

Ele realmente existe, mas é bem antigo e não totalmente correto: https://magic.reactjs.net/htmltojsx.htm

Devemos reviver esse esforço. Se você quiser ajudar, faça: https://github.com/reactjs/reactjs.org/issues/484. Até agora ninguém se ofereceu para ajudar e acompanhou.

Ele realmente existe, mas é bem antigo e não totalmente correto: https://magic.reactjs.net/htmltojsx.htm

Eu usei isso várias vezes antes - é muito comum usar ao terceirizar certos componentes para pessoas que conhecem HTML/CSS, mas não JavaScript.

Então apenas dando feedback de que essa é uma ferramenta útil que as pessoas usam na prática. Existem também outros conversores online.

Um problema com essa abordagem é que ela é apenas unidirecional (apenas migrar _para_ reagir). Esse problema não é especial para o React.

Espero que facilite muito as coisas...

Um problema com essa abordagem é que ela é apenas unidirecional (apenas migre para reagir). Esse problema não é especial para o React.

Por quê? Deve ser ainda mais fácil o contrário - basta executar ReactDOMServer.renderToString .

Aguardando pacientemente o lançamento

@gaearon

Por quê? Deve ser ainda mais fácil o contrário — basta executar ReactDOMServer.renderToString.

Ok, então para o contexto o problema discutido é: Eu quero que as pessoas que escrevem html/css e não conhecem JavaScript o suficiente para trabalhar no código JS possam trabalhar na marcação/estilo/layout dos componentes.

Uma maneira de fazer isso agora é fazer com que eles o desenvolvam em html/css e usem htmltojsx. Isso funciona muito bem para mim.

O problema é que agora tenho que manter todas as alterações de marcação/estilo/layout no React.

Se eu chamar ReactDOMServer.renderToString , na verdade, eu obteria HTML estático, mas esse HTML estaria faltando todo o código do componente real, então não é viável fornecê-lo às pessoas da interface do usuário e usar sua saída, pois eu teria que reescrever tudo minha lógica.

Coisas como react-sketchapp são uma boa abordagem possível para o problema, mas espero uma abordagem mais genérica que me permita fazer isso usando html/css regular. Por exemplo - através de alguma forma de metadados e mantendo IDs de reação nos elementos.

Eu entendo totalmente que isso não está no escopo do núcleo ReactDOM, mas está definitivamente em seu domínio e é um problema interessante.

Isso não é de alta prioridade - eu só queria explicar por que o htmltojsx é útil para alguns de nós, mesmo fora do contexto de uma migração :)

Eu quero que as pessoas que escrevem html/css e não conheçam JavaScript o suficiente para trabalhar no código JS possam trabalhar na marcação/estilo/layout dos componentes.

Quão grande é esse problema, e quão difícil seria ensiná-los um pouco de JSX? As alterações precisam ser revisadas por um engenheiro experiente em React de qualquer maneira.

Desculpe se isso ficar muito fora do tópico, mas acredito que apenas HTML/CSS não é suficiente hoje em dia.

( @gaearon sinta-se à vontade para esconder isso se ficar barulhento, pois é uma resposta sobre o já pequeno comentário OT acima)

Quão grande é esse problema, e quão difícil seria ensiná-los um pouco de JSX? As alterações precisam ser revisadas por um engenheiro experiente em React de qualquer maneira.

Bem, isso exigiria o seguinte:

  • Trabalhe apenas com contratados que estejam familiarizados com sua pilha React atual. É muito mais difícil encontrar pessoas que aprendam componentes de estilo
  • Instale o Node (npm), sua pilha (React, webpack etc), e tudo o mais necessário para executá-lo em cada computador das pessoas da interface do usuário e mantê-lo atualizado.
  • Ensine a eles um pouco de programação básica e JavaScript, aprendendo como trabalhar com as ferramentas de desenvolvimento, erros de console etc.
  • Ensine-os React, qual é a sua sintaxe, coisas como className , o que key significa etc.
  • Trabalhe apenas com contratados e freelancers que estejam dispostos a trabalhar dessa maneira, em vez de produzir HTML/CSS. Isso geralmente também torna as coisas mais caras.

Agora, como mencionado acima, coisas como react-skeptchapp são uma maneira útil de tornar isso mais acessível e fácil para as pessoas da interface do usuário - mas ainda exige que elas aprendam muito.

Eu entendo totalmente por que você está perguntando isso e não tenho certeza de que esse seja um problema comum (suspeito que seja). Independentemente disso, não acho que esteja no escopo do futuro do núcleo do ReactDOM.

Isso está fora do tópico :-) Vamos continuar esta discussão no Twitter ou em outro lugar.

"O comportamento para o qual você vê uma ferramenta sendo usada é um comportamento que a ferramenta incentiva"
~ Gary Bernhardt

A forma como o React está sendo usado, pois a maior parte dele não faz parte da API do React, resulta em um grande número de armadilhas que resultam em discussões como essa onde todos ficam confusos e frustrados. O uso de uma palavra-chave reservada, como class é ruim por causa de javascript, html ou react-se?

Voltando às mudanças feitas no 16.3 (se bem me lembro), a biblioteca agora se comportaria de maneira diferente aceitando qualquer atributo passado para elementos html nativos sendo renderizados pelo vdom, lembro claramente que a maior parte da minha base de código agora estava atormentada por bugs porque do comportamento que tivemos implementando esse padrão claramente ruim

<div {...this.props} />

Então, devo dizer que estou bastante desapontado por Dan estar sugerindo que continuemos espalhando esse código terrível em todas as bases de código.

Em primeiro lugar, não há garantias no conteúdo de props , mas na primeira vez os elementos html nativos quase sempre não farão o que se espera deles se você passar os adereços errados, mas ao mesmo tempo é considerado seguro propagar adereços pai para componentes filhos, mas na realidade isso é terrivelmente preguiçoso

<Child {...props} />

const Child = (props) => <div {...props} />

Às vezes você nem sabe o que está renderizando e esse problema se torna ainda mais difícil de lidar. Também é extremamente difícil verificar esses tipos de componentes usando sistemas de tipos, porque isso significaria que a maioria dos componentes é necessária para implementar várias interfaces aleatórias que devem compartilhar entre si, é uma toca de coelho profunda e profunda.

Se uma reescrita para reagir for feita para corrigir isso, eu esperaria que os designers por trás disso percebessem o dano que esses padrões ruins causam à base de código, em vez de dobrar as decisões ruins.

Devemos lembrar que o jsx é construído em cima do javascript, e usar as "idiossincrasias" do javascript como desculpas para entrar em conflito deliberadamente com a linguagem no uso de palavras-chave é um mau primeiro passo para consertar a API, eu sugiro que em vez de começar uma guerra contra a linguagem você se afastaria dela inteiramente

@gaearon Quanto tempo! :) (ps. desculpe por tl; dr à frente)

De qualquer forma, eu só queria dar algumas dicas sobre o que aprendi com minhas próprias aventuras. Eu fiz meu próprio derivado React "mínimo" que agora uso para aplicativos críticos de desempenho/recurso. Foi inicialmente apenas um experimento paralelo divertido, mas eu estava vendo melhorias de desempenho além de +300% em casos do mundo real para renderização/atualização/exclusão inicial, incluindo muitos outros benefícios. Isso sem usar um manipulador de eventos em pool também.

IIRC uma grande parte disso vem simplesmente da minha própria biblioteca ignorando toda a lógica React-props e simplesmente alimentando atributos diretamente em setAttribute, estilos direto em style.setProperty, listeners direto em addEventListener e assim por diante. Portanto, a interface básica do elemento DOM se parece com isso `{attributes: {}, style: {}, listeners: {}, className: "", ...}, é mais detalhado, mas a interface agora é pequena e trivial para implementar e é extremamente rápido. Isso provavelmente é muito extremo para você, mas me serviu muito, muito bem.

Algo que tenho feito também é descartar o CSS completamente, todos os estilos são inline. É muito, muito mais rápido do que você esperaria e vem com muitos benefícios práticos interessantes, também evita o custo da análise CSS inicial do navegador (que é surpreendentemente cara) e a correspondência de seletores que recupera a maior parte da sobrecarga. Eu posso alcançar facilmente 60 FPS estáveis ​​e muito além no meu laptop com pouca potência para hierarquias complexas (sem qualquer poda de árvore).

Imagino que a maior parte disso não seja realmente útil para você, mas talvez haja algo interessante aí. De qualquer forma, minha principal reclamação com HTML+React é que os componentes de usuário do React não expõem nenhuma interface para layout/posicionamento (e provavelmente até certo ponto também eventos) sem recorrer ao CSS. Simplificando, se eu criar um ButtonComponent e depois usá-lo, por padrão ele não pode ser posicionado ou integrado em um layout sem; implementando lógica de propósito especial dentro dele, envolvendo-o em um elemento fictício que pode ser posicionado ou expondo um prop de estilo que é mesclado nos estilos usados ​​para o elemento raiz ButtonComponent. Nenhum deles é perfeito, e mesclar estilos como estão é perigoso, pois é fácil colocar estilos que você não deveria. Essencialmente, o problema é que, nos limites dos componentes, um subconjunto das propriedades disponíveis deve ser público (posicionamento/layout) e algum interno (estilo visual).

Outra coisa que faço é a separação entre componentes e conteúdo/filhos. Por exemplo, os componentes DOM não recebem uma lista de filhos, em vez disso, aceita uma instância de conteúdo. A instância de conteúdo implementa a lógica de reconciliação e a renderização de filhos, o que significa que você pode ter diferentes implementações para diferentes propósitos. Os casos de uso mais óbvios são; principalmente hierarquias estáticas versus filhos gerados dinamicamente. Assim, as hierarquias estáticas que compõem a maioria podem ser implementadas usando uma lógica mais rápida e simples, enquanto os filhos gerados dinamicamente podem ter estratégias configuráveis. Também abre a possibilidade de ter "componentes de conteúdo" que podem ser usados ​​para gerenciar de forma inteligente, por exemplo, layouts de flexbox sem indiretas desnecessárias.

Relacionado a isso e algo que acho que o React erra são as crianças, ainda não cheguei a uma conclusão ou solução específica. Mas eu acredito fortemente que há um problema fundamental no React em que você não pode fazer bolhas de props da raiz para um ponto arbitrário na hierarquia sem renderizar novamente cada elemento entre esses dois pontos e a poda eficaz também é problemática. O desempenho é principalmente "bom o suficiente" e a complexidade adicional de gerenciar isso no React pode não valer a pena resolver. Mas em meus experimentos até agora eu consegui reduzir os custos totais de atualização da raiz para meras frações com quantidades muito pequenas de código trivial, mas minha intuição diz que não é muito compatível com a filosofia do React ou seu modelo filho simplista.

Algo que definitivamente não é para você, mas um grande recurso da minha biblioteca é que ela basicamente fornece apenas um "elemento DOM base" mínimo para uso geral. A ideia é que você pode estender/substituir e implementar trivialmente seus próprios comportamentos específicos de baixo nível se estiver desenvolvendo um projeto grande com requisitos/circunstâncias específicos de maneira muito barata e sem recorrer a "hacks", por exemplo, se você for muito sensível orientado, quer fazer tratamento de estilo especial, etc. Também significa que diferentes versões são compatíveis e podem ser executadas lado a lado desde que a ABI seja a mesma (uma alteração deve ser extremamente rara e muito simples de corrigir ). Isso também significa que você pode ser bastante opinativo na interface do elemento DOM sem ter que ser abrangente e tentar resolver o problema de todos.

De qualquer forma, talvez principalmente apenas divagando e provavelmente não estou transmitindo a maioria dos conceitos muito bem, mas talvez haja alguma informação interessante para você de alguém que foi na direção oposta. A maior parte provavelmente não é relevante para você simplesmente porque você está visando a "simplicidade", mas quem sabe :)

Além disso, antes que eu esqueça, você pode estar interessado na minha função objectKeyValueReconcile , especificamente otimizada para ser extremamente rápida para comparar adereços anteriores/seguintes para cenários do tipo React. É responsável por ganhos de desempenho bastante significativos no mundo real para mim.

https://github.com/syranide/surgical/blob/master/packages/surgical/private/objectKeyValueReconcile.js

imho eu abandonaria a ideia de "classe". JSX acabará por morrer.

Quais são os pensamentos de adicionar suporte para eventos DOM/window não baseados em elementos ao React DOM? Com a possível remoção de eventos sintéticos, suspeito que ainda haveria alguma forma de coleta/atualização/lote de eventos. Os eventos de pressionamento de tecla, redimensionamento e rolagem da janela são cenários comuns que vêm à mente, mas possivelmente ser capaz de suportar a maioria/toda a lista em https://developer.mozilla.org/en-US/docs/Web/Events seria ser benéfico por trás da mesma abstração.

Isso também é discutido na edição aberta mais antiga #285 😄.

@gaearon

O efeito prático de className -> class será:

({ className }) => <div className={className} />

se tornará

({ ...rest }) => <div class={rest.class} />

Esta mudança causará um pouco de dor enquanto os benefícios são inteiramente acadêmicos . Vimos outras comunidades fazerem coisas semelhantes - por exemplo, considere que python3 foi lançado pela primeira vez há uma década e ainda estamos discutindo sobre isso. Uma parcela considerável da comunidade não fez a transição e nunca fará. Por favor, reconsidere.

@kans

Ou isto:

props => <div class={props.class} />

Isso é de complexidade semelhante à função original.

Eu gostei className porque class é uma palavra-chave em js, mas não pense que é um grande negócio de qualquer maneira. Eu prefiro estilo com algo como glamouroso, então, isso não é algo que me afeta. Talvez eu tenha usado className algumas dúzias de vezes nos últimos anos? Quase nunca.

Embora um pensamento que me ocorreu a favor de class é que a maioria das pessoas que realmente usa className está usando css e espera o modelo html/css de class . O objetivo principal dessa prop é realmente apenas vincular com código css, certo, então por que não apenas chamá-lo de classe como um usuário de html/css espera?

IMO fora do código do sistema de design, o desenvolvimento realmente idiomático do React normalmente não usaria className ou class muito de qualquer maneira. Quando eu preciso usar classes para css, é principalmente isolado para alguns pequenos componentes de interface do usuário. Praticamente qualquer coisa usada na camada de aplicativo é de nível superior (como, digamos, <Columns verticalAlign="center"> ou <BodyText /> ).

Então eu acho que eu me pergunto se renomear de className para class torna mais fácil para o tipo de pessoa que usa o prop de qualquer maneira (mais fácil entrar no desenvolvimento React, mudar contextos, não ficar com raiva , etc), por que não renomeá-lo?

Reduza o tamanho do pacote por favor.

Como esta é uma grande atualização, talvez possamos corrigir a nomenclatura do ciclo de vida do React também!

ou seja shouldComponentUpdate => shouldUpdate , etc. Esta nomenclatura é mais do que boba.

@AlexGalays

Como esta é uma grande atualização, talvez possamos corrigir a nomenclatura do ciclo de vida do React também!

ou seja, shouldComponentUpdate => shouldUpdate, etc. Esta nomenclatura é mais do que boba.

Nomes de gancho de ciclo de vida mais longos são menos ambíguos quando pesquisados. Nomes mais curtos são muito genéricos e dependem do contexto em que estão localizados, portanto, podem coincidir coincidentemente com outra base de código grande (correspondência de falso positivo).

Os métodos do ciclo de vida fazem parte do núcleo do React, e esse problema é apenas sobre o react-dom.

@ljharb
Opa, mesmo!

@sompylasar
Desculpe, isso simplesmente não é um bom motivo (trocadilho intencional, reasonReact corrigiu os nomes dos métodos :)). Nós também não prefixamos todos os nossos módulos por seus nomes de pacotes e os achamos bem. De qualquer forma, vou parar de falar sobre isso, pois o react-core está fora do escopo desta questão.

Adoraria ver essas mudanças.
Espero que eles sejam implementados com a interoperabilidade de elementos personalizados em mente.

Gostaria de saber se vale a pena mover algumas das discussões para tópicos separados no fórum (https://discuss.reactjs.org)? Como os problemas do GitHub não são encadeados como postagens do fórum, fica complicado discutir várias coisas diferentes no mesmo problema.

A mudança de className -> class me parece interessante 😺

Assista, projetos React 2019

const {
  class: className, // YouKnowIamRight PepeHands
  someFancyProp,
  ...restProps
} = props

Eu vejo isso chegando com certeza.

Adoro poder copiar e colar HTML e não ter que alterar className mas ao mesmo tempo vejo os problemas que a palavra-chave reservada class pode trazer.

Neste ponto, eu preferiria ficar com className a menos que você tenha uma forte preocupação de engenharia sobre isso (não preferência pessoal)

Mas essa é apenas a minha opinião pragmática.

Embora eu entenda o atrito adicional de não poder destruir o identificador class , sinto que muitas pessoas neste tópico superestimam o número de vezes que precisam receber o nome da classe como um suporte.

Passar className para um componente React (que não é apenas um elemento DOM) significa que você cria blocos de construção bem pequenos sem fornecer novas abstrações ou esse componente expõe alguns de seus detalhes de implementação. No primeiro caso (por exemplo, componente <Button /> ) você provavelmente gostaria de seguir o exemplo de @gaearon e encaminhar o "resto" dos adereços para o elemento DOM também. No segundo caso, talvez o atrito adicional o forçaria a evitar fazer a coisa e encontrar uma solução melhor.

Da minha humilde experiência, tive que copiar e colar HTML para JSX (e substituir class por className ) mais vezes do que me lembro de fazer um componente que recebe className .

Espalhar todos os adereços para um HTML é um anti padrão. Se alguém no futuro incluir um prop extra que corresponda a um atributo HTML, isso mudará inesperadamente o comportamento. Se o IE adicionar um novo atributo, você será expulso.

@philipwhiuk se você espalhar apenas os adereços que não usa, não haverá problemas de comportamento.

@j-f1

se você apenas espalhar os adereços que não usa, não haverá problemas de comportamento.

Na verdade. Se você adicionar uma nova opção à API do seu componente, essa opção deixará de ser passada para o nó DOM subjacente. Alguém pode depender desse atributo exato sendo definido no elemento e então você quebra essa pessoa. Espalhar todos os adereços não utilizados para qualquer coisa abaixo significa que qualquer adição à API do seu componente é uma mudança importante.

Aliás, eu usei um exemplo aleatório onde você desconstrói o valor de class mas não se corta nesse detalhe.

Muitos de vocês (sim, você faz) desconstruir quase todos os valores de props e state em vez de usar a notação de ponto por não motivos, além de evitar digitar algum texto extra.

Então é por isso que estou enfatizando a situação, mas não vá para o lado e focando em espalhar adereços ou qualquer outro tópico paralelo que você possa falar sobre isso.

Se você for um pouco mais pragmático, falaria sobre as implicações técnicas em vez de suas preferências pessoais, mas não vejo ninguém dizendo nada sobre as implicações técnicas de className .

Outra coisa que você precisa prestar atenção é que você está fazendo com que os colaboradores do Core se concentrem em algo que é uma questão de preferências pessoais (prove que estou errado, só porque quero que você pense nisso de forma pragmática)

Seu tempo, esforço e dinheiro (da empresa) são limitados, então melhor se a comunidade entender que há coisas melhores para focar nossa atenção e se alguém da equipe principal gastar uma hora em algo que preferimos que eles usem em a próxima grande coisa para o React, nenhum código de refatoração para tal mudança.

Mas, novamente, minha opinião pragmática.

Falando em polyfills, não acho que o react deva tentar detectar se o usuário especificou polyfills "bons".
(por exemplo hasBadMapPolyfill no código)
O React não deve ser responsabilizado por todos os erros aleatórios que alguém pode cometer em um projeto de programação.

@AlexGalays React depende do uso de uma implementação Map com semântica correta. Se os usuários estiverem usando um polyfill não compatível, o aplicativo pode quebrar de maneiras inesperadas e confusas, portanto, é útil avisar com antecedência nesse caso.

Isso também é feito apenas na compilação de desenvolvimento, portanto, não há sobrecarga para isso na produção.

Eu amo este React Fire e você continuaria trabalhando nisso, pois parece um passo mais interessante para modernizar o ReactDOM.

Seria possível reagir fogo para não religar manipuladores de eventos?

class Compo exntends Compoent {
 onClick() {
   ...
 }
  render() {
   <button onClick={this.onClick} >click me </button>
  }
}

Eu não acho que alguém realmente queira que o manipulador de eventos seja rebote. E nos raros casos em que você poderia vinculá-lo manualmente

@cullophid

Seria possível reagir fogo para não religar manipuladores de eventos?

Você pode vincular o método à classe uma vez usando ligações automáticas de função de seta ou vinculando a função em seu construtor. Se houver parâmetros exclusivos que você deseja encadear ao evento, você pode procurar memorizar os manipuladores de eventos ou anexar atributos DOM aos próprios nós e acessá-los por meio de event.currentTarget .

class Compo extends Compoent {
 onClick = () => {
   ...
 }
 render() {
   <button onClick={this.onClick}>click me</button>
 }
}

Outro benefício de simplificar o sistema de eventos (podemos voltar aos eventos DOM brutos sem nenhum pooling como TODOS os frameworks fazem? :)) é que também é mais fácil digitar estaticamente.

Parece um ótimo plano! Seria muito bom ter suporte ao IE 11 (mesmo que isso signifique enviar nossos próprios polyfills, o que é totalmente bom). Como alguém que trabalha com clientes do governo, quando eles vão parar de usar o IE 11 é uma completa incógnita :(

@MatthewHerbst mesmo barco, nossos clientes usam o IE 11 e temos tráfego suficiente 😢

Só queria entrar na conversa para dizer que tudo isso é super emocionante. A única coisa que li que me preocupou foi:

é possível que não tentemos suavizar algumas das diferenças de navegador existentes

No momento, adoro saber que o sistema de eventos do React "simplesmente funcionará" em qualquer navegador compatível com o React. Receio que essa alteração signifique que será responsabilidade do aplicativo responder por problemas entre navegadores. Isso provavelmente introduziria muitos bugs difíceis de rastrear. ...pelo menos seria para meus aplicativos. :)

De qualquer forma, obrigado como sempre pela ótima biblioteca.

@kentcdodds havia mencionado a integração do JSX 2.0 como uma possível ideia que eu estava lendo a Estratégia e não vi nada que parecesse relacionado a isso. Eu queria saber se isso foi apenas no ar ou algo que será adiado para o futuro?

Deixe o IE morrer! Não suporte navegadores absolutamente desatualizados. Não há razão, mesmo para empresas restritivas, para não mudar para um navegador atualizado. Você verá que o IE11 em suas estatísticas até que você e a web parem de suportá-lo.

@hbroer Software legado?

@hbroer ninguém fica em um navegador antigo porque seus sites ainda funcionam, eles fazem isso porque não têm escolha ou não sabem como atualizar. Quebrar um site para esses usuários é extremamente hostil e os deixa sem um navegador atualizado, mas sem nada.

  • "não sei como atualizar" - não é problema nosso, mas podemos colocar nas mensagens "instalar um novo navegador" com uma lista de navegadores e talvez com texto de ajuda e número de telefone da Microsoft Hotline ^^
  • "não tem escolha" - Certo, mas a organização tem que atualizar seu ambiente. Se suas ferramentas não funcionarem, eles funcionarão.

eu odeio codificar para o passado e não posso usar o benefício da nova tecnologia, porque 90% dos codificadores ainda suportam os navegadores ruins dos 15% consumidores que vivem no século passado. ^^ Não quero ter esse "oh, o que há com esse Internet Explorer 6 nerds, temos que apoiar esses 15%" novamente pelos próximos 10 anos.

btw M$ costura para trazer o Edge para Windows 7 e 8 com sua mudança para o webkit.

@hbroer tudo é problema nosso se afetar os usuários. Tenha alguma empatia por outros humanos.

(Separadamente, M$ é uma referência bastante juvenil e muito datada do final dos anos 90 que você pode remover; ficarei feliz em remover isso de lado se você fizer isso)

Entendo, aqui estão muitos fanboiz de M$. :DI realmente se importa com os humanos, mas não com as organizações que bloqueiam a progressão da tecnologia, ou os programadores que pretendem ter que suportar essa velha porcaria ao longo dos anos. Não tenho nenhum problema com um pacote adicional que torna uma biblioteca "compatível com porcaria antiga". Mas uma biblioteca em 2019 deve ser codificada com tecnologia >=2019 em mente, e não com tecnologia <=2013. Já é ruim o suficiente ter que apoiar aquele (oh, vamos fazer isso um pouco de outra maneira) safári e (antiga) porcaria de borda.

microfone

@hbroer , na verdade, o navegador Android antigo e o safari antigo são mais um problema do que qualquer navegador da Microsoft. não se trata de ser "fanboi", mas de ser profissional, e usar o termo "M$" não é.

E não, não é "ruim" de forma alguma apoiar a tecnologia antiga, é a coisa moral e ética a se fazer. O que é ruim são os sites que "funcionam melhor no X", seja o Netscape Navigator, o IE 6 ou o Chrome mais recente.

Entendo, aqui estão muitos fanboiz de M$.

@hbroer eu vejo aqui uma pessoa com ataques generalizados ad hominem.

Mas uma biblioteca em 2019 deve ser codificada com tecnologia >=2019 em mente, e não com tecnologia <=2013.

Não, não deveria.

Se você demorasse um segundo e analisasse os padrões da lista de navegadores, ficaria surpreso. Em vez disso, você recorre a ataques ad hominem e insultos no nível do refeitório da escola.

Depois de obter usuários suficientes, o IE11 se torna um pedaço considerável de pessoas que acessam seu site. Em um trabalho anterior, tínhamos cerca de um milhão de pessoas por mês acessando nosso site pelo IE11.

browsers

Se você quiser suporte a porcaria antiga, adicione preenchimentos poli. Não há razão para não codificar para o futuro e o presente. O suporte à tecnologia antiga torna os aplicativos da Web mais gordos e mais lentos do que o necessário.

Ps eu vejo uma pessoa que não sabe ler sarcasmo e não se importa com smilies ^^

@hbroer Você está mostrando que o IE11 é o presente, então espera-se que estejamos codificando para isso.

E mais uma vez. Veja o valor padrão em https://browserl.ist.

Ps eu vejo uma pessoa que não sabe ler sarcasmo e não se importa com smilies ^^

É, não. Esta é uma tática comum empregada por trolls e valentões de playground. "O quê?! Eu não te insultei! Foi só uma brincadeira!".

0,20% das pessoas do planeta, mesmo filtradas por "os que usam a internet", são 6,4 milhões de seres humanos. As porcentagens são totalmente irrelevantes. Código para humanos; o passado e o futuro, e o tamanho do seu pacote, não importa.

Se você deseja codificar para o tamanho do pacote humano, assim como a compatibilidade do navegador, certamente importa. Os usuários não apenas esperam que as coisas funcionem, mas também devem ser rápidos para carregar.

Agora em 2019 vou usar para novos projetos o css grid (que tem apenas suporte experimental no IE11), e vou transpilar para o ES6 e não quero entregar polyfills para esse navegador desatualizado. Os usuários do IE11 simplesmente recebem uma mensagem: Atualize seu navegador ou use uma alternativa.

Há pessoas por aí que não querem usar java script. Você se importa com eles? Você não vê esses caras nas estatísticas. E eu não estou em estatística também, como muitas outras pessoas que bloqueiam essas ferramentas.

Eu fico de olho em todos os navegadores que não estão desatualizados. Eu apoio o edge, que tem menos usuários do que essa porcaria do IE11, por causa do Windows 7 (que suporta termina em janeiro de 2020), e as pessoas modernas usam navegadores modernos. ^^

Ninguém impede você de usar polyfills e algo como um pacote de compatibilidade. Mas o núcleo deve estar atualizado e não ficar para trás apenas por causa de uma peça de um antigo navegador de tecnologia M$.

O que estou perdendo em muitos frameworks javascript é o LTS. É sobre isso que podemos falar. Se você criar uma página moderna com recursos do presente, é bom usar uma estrutura de tecnologia atualizada. E se você está construindo um webapp para coisas b2b que precisam do máximo de estabilidade e compatibilidade, então você pode usar uma versão LTS. Ou use nocaute. Então você pode apoiar as poucas pessoas 100t que ainda estão usando um Windows XP não atualizado com IE6 ^^

A compatibilidade está claramente listada em "compensações" no post original, portanto, ter suporte perfeito para navegadores antigos já é um foco secundário.

Eles exigirão mais polyfills e integração se você precisar apoiá-los, mas essa seria sua escolha . Você também pode criar vários pacotes para diferentes destinos de navegador e fornecer o menor JS possível para cada visitante, para que não afete todo o seu público.

O progresso no próprio React Fire parece não ser afetado, então não há realmente nada a ganhar com esse debate. Vamos seguir em frente, por favor, e voltar ao assunto principal.

Esta seria uma boa oportunidade para resolver o #6410? Parece semelhante em impacto às alterações propostas para onChange / onInput .

Atualização de 5 de junho de 2019

Faz algum tempo. Aqui está uma pequena atualização sobre onde estamos.

Começamos a trabalhar no Fire em dezembro. Há algum trabalho em andamento em https://github.com/facebook/react/pull/14382 e outros tópicos. No entanto, quando começamos a remover partes do sistema de eventos que achávamos desnecessárias ou desatualizadas, descobrimos muitos casos extremos em que estava sendo muito útil e preveniu bugs - mesmo em navegadores modernos. Ainda queremos reduzir o inchaço do legado, mas não está claro que estar mais perto de eventos DOM brutos seja a melhor direção na prática. Reduzir o código da biblioteca apenas para adicioná-lo novamente várias vezes no código do aplicativo não é a melhor compensação. E nem sempre é possível corrigi-lo no nível do aplicativo.

Separadamente, enquanto trabalhávamos no FB5 , percebemos que mesmo usando React, hoje existem dificuldades significativas na implementação de interfaces de usuário que funcionam e são ótimas em dispositivos de mouse e touch. Mesmo coisas básicas, como botões, parecem muito diferentes com o mouse e o toque quando você usa eventos como onClick , e fica ainda mais difícil obter um comportamento consistente com foco, foco etc.

Então, quando começamos a trabalhar no Fire, pensamos que talvez um sistema de eventos personalizado fosse desnecessário. Mas após a remoção do protótipo, percebemos que nosso sistema de eventos é de fato nossa maior alavanca para corrigir esse conjunto de problemas .

Como resultado desta investigação, pausamos temporariamente o trabalho em outros itens que fazem parte do React Fire e decidimos focar apenas no sistema de eventos primeiro. Esse projeto ficou conhecido como React Flare (https://github.com/facebook/react/issues/15257). É desafiador o suficiente por si só e afeta os outros itens desta lista, por isso estamos nos concentrando primeiro isoladamente.

O objetivo do React Flare é facilitar a criação de interfaces de usuário que sejam ótimas para desktop e dispositivos móveis, com mouse e toque, e que sejam acessíveis. Inclui APIs declarativas para gerenciar interações como Press, Hover e Focus. Ao contrário do sistema de eventos React atual, o design do Flare não infla o pacote para eventos que você não usa - e deve permitir reduzir a quantidade de código nas bibliotecas de interface do usuário que lidam com eventos de mouse e toque.

O React Flare ainda é um experimento, mas estamos bastante confiantes em sua direção geral e planejamos torná-lo oficialmente disponível em código aberto. (Por enquanto só funciona se você compilar manualmente a partir do master, e não há garantias semver, pois estamos trabalhando ativamente nele.) Assim como Fire, "Flare" é apenas um codinome - quando o lançarmos, ele terá nomeação adequada, documentação, etc. Talvez react/events ou algo assim. Gostaríamos de oferecer eventos equivalentes em React Native também.

Após terminarmos a implementação inicial do React Flare, voltaremos à lista React Fire e reavaliaremos todos os outros pontos usando o que aprendemos com ela. Ainda é provável que, se o Flare assumir um conjunto "mais rico" de eventos, possamos simplificar o tratamento de eventos "básico" no React DOM e remover vários polyfills. Obrigado a todos pela discussão até agora, e espero que isso seja útil.

Ótimo trabalho! Portanto, o sistema de eventos ainda é necessário para balancear eventos de mouse e touch, mas será leve e independente do React.

O "React Flare" virá como parte do pacote padrão do React ou precisará de uma instalação adicional, considerando a quantidade de APIs com as quais ele será enviado?

Gostaríamos de evitar que código não utilizado fosse empacotado. Portanto, a intenção atual é que seja opt-in por API. Talvez pontos de entrada separados em um único pacote.

Este sistema de eventos de mouse e toque alavanca PointerEvent ? Eu não vi uma menção a esse padrão da web na atualização anterior, então eu só queria chamar sua atenção.

Eventos de ponteiro são eventos DOM que são disparados para um dispositivo apontador. Eles são projetados para criar um único modelo de evento DOM para manipular dispositivos de entrada de apontamento, como mouse, caneta/stylus ou toque (como um ou mais dedos). O ponteiro é um dispositivo independente de hardware que pode direcionar um conjunto específico de coordenadas de tela. Ter um único modelo de evento para ponteiros pode simplificar a criação de sites e aplicativos e fornecer uma boa experiência ao usuário, independentemente do hardware do usuário.

E aqui está um link direto para a compatibilidade do navegador atual .

@jonathantneal Sim, o novo sistema usa muito eventos de ponteiro – com fallbacks para eventos de mouse/toque quando não há suporte para eventos de ponteiro.

Estou preocupado que https://github.com/facebook/react/issues/11347 não tenha sido abordado neste problema. Reagir reprovados https://custom-elements-everywhere.com.

Por favor, considere a raiz sombra ao redesenhar o sistema de eventos - apenas anexar à raiz React não resolveria a maioria dos problemas hoje, apenas anexar ao elemento (https://github.com/facebook/react/issues/9242, https:// github.com/facebook/react/issues/15759, https://github.com/facebook/react/issues/13713, https://github.com/facebook/react/issues/11827)

Nesta atualização: https://github.com/facebook/react/issues/13525#issuecomment -499196939 @gaearon menciona:

No entanto, quando começamos a remover partes do sistema de eventos que achávamos desnecessárias ou desatualizadas, descobrimos muitos casos extremos em que estava sendo muito útil e preveniu bugs - mesmo em navegadores modernos.

Eu estava curioso se uma lista desses casos de borda está documentada em algum lugar?

@gaearon agora que o Flare saiu (SCNR), existe um plano atualizado (em relação à atualização de 5 de junho de 2019 ) como proceder?

E como @trusktr , eu também gostaria que o #11347 fosse abordado aqui.

Pode ser dividido polyfills em outro pacote, especialmente aquele que não é relevante para os principais navegadores evergreen.

Olá a todos, já faz um tempo e nós tentamos algumas dessas coisas de vez em quando.

Deixe-me dar uma atualização sobre cada um:

Ainda queremos fazer isso, mas decidimos "reservar" o React 17 para ter o mínimo possível de alterações de quebra para que ele possa se concentrar no próximo item desta lista. Portanto, essa alteração aguardará até o React 18.

  • Anexe eventos na raiz do React em vez do documento (https://github.com/facebook/react/issues/2043). Anexar manipuladores de eventos ao documento se torna um problema ao incorporar aplicativos React em sistemas maiores. O editor Atom foi um dos primeiros casos que se depararam com isso. Qualquer grande site também desenvolve casos de borda muito complexos relacionados a stopPropagation interagindo com código não-React ou através de raízes React (https://github.com/facebook/react/issues/8693, https://github .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). Também desejaremos anexar eventos a cada raiz para que possamos fazer menos verificações de tempo de execução durante as atualizações.

Estamos fazendo isso no React 17. Isso acabou sendo uma grande parte do trabalho, mas felizmente está finalizado.

  • Migre de onChange para onInput e não faça polyfill para componentes não controlados (https://github.com/facebook/react/issues/9657). Consulte o problema vinculado para obter um plano detalhado. Tem sido confuso que o React use um nome de evento diferente para o que é conhecido como evento input no DOM. Embora geralmente evitemos fazer grandes mudanças como essa sem benefícios significativos, neste caso também queremos alterar o comportamento para remover alguma complexidade que é necessária apenas para casos extremos, como a mutação de entradas controladas. Portanto, faz sentido fazer essas duas mudanças juntas e usar isso como uma oportunidade para fazer onInput e onChange funcionarem exatamente como os eventos DOM funcionam para componentes não controlados.

Provavelmente voltaremos a isso, mas não está claro quanto churn vale a pena fazer aqui. Então isso ainda é TBD.

  • Simplifique drasticamente o sistema de eventos (https://github.com/facebook/react/issues/4751). O sistema de eventos atual quase não mudou desde sua implementação inicial em 2013. Ele é reutilizado em React DOM e React Native, por isso é desnecessariamente abstrato. Muitos dos polyfills que ele fornece são desnecessários para navegadores modernos, e alguns deles criam mais problemas do que resolvem. Ele também é responsável por uma parte significativa do tamanho do pacote React DOM. Não temos um plano muito específico aqui, mas provavelmente faremos um fork do sistema de eventos completamente e, em seguida, veremos o quão mínimo podemos torná-lo se ficarmos mais próximos do que o DOM nos dá. É plausível que nos livremos completamente dos eventos sintéticos. Devemos parar de borbulhar eventos como eventos de mídia que não borbulham no DOM e não têm uma boa razão para borbulhar. Queremos manter alguns recursos específicos do React, como borbulhar através de portais, mas tentaremos fazer isso por meios mais simples (por exemplo, re-despachando o evento). Eventos passivos provavelmente farão parte disso.

Tentamos isso no início de 2019 e um sistema de eventos realmente mínimo não funcionou muito bem em nossos testes internos. Houve um pouco de normalização entre navegadores que o React está fazendo, o que ainda é útil para pessoas com navegadores mais antigos, ou em mais áreas de nicho, como editores de entrada de rich text usando contentEditable . Dito isso, como parte de nosso trabalho de anexar eventos às raízes, removemos muita abstração do sistema de eventos para que seja mais fácil de entender e melhorar no futuro. Como parte do React 17, estamos removendo o "pooling de eventos" que causou muita confusão, e também não estamos mais borbulhando o evento onScroll . Provavelmente seguiremos parando o borbulhar de eventos de mídia no React 18, aproximando o comportamento do React ao do navegador. Salvamos alguns bytes com o novo sistema de eventos, mas eles foram ocupados por novos recursos nos quais estamos trabalhando, portanto, isso não levará a uma diminuição geral do tamanho do pacote.

  • classNameclass (https://github.com/facebook/react/issues/4331, veja também https://github.com/facebook/react/issues/13525#issuecomment- 417818906 abaixo). Isso foi proposto inúmeras vezes. Já estamos permitindo passar class para o nó DOM no React 16. A confusão que isso está criando não vale as limitações de sintaxe contra as quais está tentando se proteger. Não faríamos essa mudança por si só, mas combinada com tudo o mais acima faz sentido. Observe que não podemos permitir ambos sem avisos, porque isso dificulta muito o manuseio de um ecossistema de componentes. Cada componente precisaria aprender a lidar com ambos corretamente, e existe o risco de eles entrarem em conflito. Como muitos componentes processam className (por exemplo, anexando a ele), é muito propenso a erros.

Esta foi a parte mais controversa da proposta. Desde então, lançamos Hooks, que incentivam a escrita de componentes de função. Em componentes de função, geralmente sugerimos usar desestruturação para props, mas você não pode escrever { class, ... } porque seria um erro de sintaxe. Portanto, no geral, não está claro se isso é ergonômico o suficiente para realmente seguir adiante. Acho plausível revisitarmos isso no futuro, ou pelo menos fazer class não avisar e deixar as pessoas fazerem o que quiserem. Mas, por enquanto, vamos arquivar essa ideia.

Olá, é um ótimo artigo!
Só queria saber se existe algum plano em andamento para reduzir o tamanho do produto React-DOM? Para aplicativos móveis, ainda é uma sobrecarga, pois o navegador analisará mais de 100 KB de React-DOM JS e outros módulos. Em seguida, JS específico do aplicativo.
Para páginas ricas em conteúdo, está causando maior bloqueio e maior TTI.

Alguma idéia de quando podemos ver essas mudanças?

@morevolk-latei Em suas medições, quanto tempo é gasto analisando 100 KB do ReactDOM?

Esta página foi útil?
0 / 5 - 0 avaliações