React v16.4.0: Eventos de Ponteiros

23 de Maio de 2018 por Andrew Clark

A última release minor adicionou suporte para um recurso solicitado frequentemente: eventos de ponteiros!

Também foi incluso uma correção de erro para o getDerivedStateFromProps. Confira o changelog completo abaixo.

Eventos de Ponteiros

Os tipos de eventos seguintes estão disponíveis agora no React DOM:

  • onPointerDown
  • onPointerMove
  • onPointerUp
  • onPointerCancel
  • onGotPointerCapture
  • onLostPointerCapture
  • onPointerEnter
  • onPointerLeave
  • onPointerOver
  • onPointerOut

Tenha em mente que estes eventos só funcionarão em navegadores que suportam a especificação de eventos de ponteiros. (No momento da redação deste texto, estão inclusas as versões mais recentes do Chrome, Firefox, Edge e Internet Explorer). Se a sua aplicação depende de eventos de ponteiros, recomendamos a utilização de um polyfill desenvolvido por terceiros. Optamos por não incluir tal polyfill no React DOM, para evitar o aumento de tamanho do pacote.

Confira este exemplo em CodeSandbox.

Enormes agradecimentos a Philipp Spiess por contribuir com esta mudança!

Correção de Erro para o getDerivedStateFromProps

getDerivedStateFromProps agora é chamado toda vez que um componente é renderizado, independentemente da causa da atualização. Anteriormente, isto era chamado se componente foi re-renderizado por seu pai, e não dispararia como resultado de um setState local. Este foi um descuido na implementação inicial que agora foi corrigido. O comportamento anterior era mais semelhante ao componentWillReceiveProps, mas o comportamento melhorado garante compatibilidade com o próximo modo de renderização assíncrono do React.

Esta correção de erro não afeta a maioria das aplicações, mas pode causar problemas com uma pequena fração de componentes. Os raros casos que importam se enquadram em uma das duas categorias:

1. Evite Efeitos Colaterais em getDerivedStateFromProps

Assim como o método render, getDerivedStateFromProps deve ser uma função pura de props e state. Efeitos colaterais em getDerivedStateFromProps nunca foram suportados, mas uma vez que agora é disparado com maior frequência do que costumava, a alteração recente pode expor erros não descobertos anteriormente.

Código com efeito colateral deve ser movido para outros métodos: por exemplo, os despachos do Flux normalmente pertencem dentro do manipulador de eventos de origem, e as mutações manuais do DOM pertencem dentro de componentDidMount ou componentDidUpdate. Você pode ler mais sobre isso em nosso post recente sobre preparando para renderização assíncrona.

2. Comparar Props Recebidas com Props Anteriores ao Computar Valores Controlados

O código a seguir assume que getDerivedStateFromProps será executado somente em alterações de props:

static getDerivedStateFromProps(props, state) {
  if (props.value !== state.controlledValue) {
    return {
      // Uma vez que este método é executado em ambas as alterações de props e state,
      // updates locais no valor controlado serão ignorados, porque a versão de props
      // sempre sobrescreve isto. Oops!
      controlledValue: props.value,
    };
  }
  return null;
}

Uma maneira possível de corrigir isto é comparando o valor de recebido com o valor anterior por armazenar as props anteriores no estado:

static getDerivedStateFromProps(props, state) {
  const prevProps = state.prevProps || {};
  // Comparando a prop recebida com a prop anterior
  const controlledValue =
    prevProps.value !== props.value
      ? props.value
      : state.controlledValue;
  return {
    // Armazena a prop anterior no state
    prevProps: props,
    controlledValue,
  };
}

No entanto, código que “espelha” props no estado geralmente contém bugs, se você utiliza a mais recente getDerivedStateFromProps ou a legada componentWillReceiveProps. Publicamos uma postagem no blog que explica esses problemas com mais detalhes e sugere soluções mais simples que não envolvem getDerivedStateFromProps().

Installation

React v16.4.0 está disponível no registro npm.

Para instalar o React 16 com Yarn, execute:

yarn add react@^16.4.0 react-dom@^16.4.0

Para instalar o React 16 com npm, execute:

npm install --save react@^16.4.0 react-dom@^16.4.0

Também fornecemos compilações UMD do React através de um CDN:

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

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

Changelog

React

React DOM

  • Adicionando suporte a especificação de eventos de ponteiros. (@philipp-spiess em #12507)
  • Chamando getDerivedStateFromProps() corretamente independente do motivo de re-renderização. (@acdlite em #12600 e #12802)
  • Correção de erro que impediu a propagação de contexto em alguns casos. (@gaearon em #12708)
  • Correção da re-renderização de componentes utilizando forwardRef() em um setState() mais profundo. (@gaearon em #12690)
  • Corrigindo alguns atributos sendo removidos incorretamente de nós de elemento personalizado. (@airamrguez em #12702)
  • Corrigindo provedores de contexto para não salvar os filhos se há um provedor de contexto herdado acima. (@gaearon em #12586)
  • Adicionando a capacidade de especificar propTypes em um componente de provedor de contexto. (@nicolevy em #12658)
  • Corrigindo um aviso de falso positivo ao usar react-lifecycles-compat em <StrictMode>. (@bvaughn em #12644)
  • Aviso quando a função de renderização forwardRef() tiver propTypes ou defaultProps. (@bvaughn em #12644)
  • Melhorar como forwardRef() e os consumidores de contexto são exibidos na pilha de componentes. (@sophiebits em #12777)
  • Alterando nomes de eventos internos. Isso pode quebrar pacotes de terceiros que dependem dos internos do React de maneiras sem suporte. (@philipp-spiess em #12629)

React Test Renderer

  • Corrigindo o suporte de getDerivedStateFromProps() para corresponder ao novo comportamento do React DOM. (@koba04 em #12676)
  • Corrigir uma falha de testInstance.parent quando o pai é um fragmento ou outro nó especial. (@gaearon em #12813)
  • Componentes forwardRef() agora são detectáveis pelos métodos do renderizador traversal de teste. (@gaearon em #12725)
  • O ReactShallowRenderer agora ignora os atualizadores de setState() que retornam null ou undefined. (@koba04 em #12756)

React ART

  • Corrigiingo o contexto de leitura fornecido a partir da árvore gerenciada pelo React DOM. (@acdlite em #12779)

React Call Return (Experimental)

  • Este experimento foi excluído porque estava afetando o tamanho do pacote e a API não era suficientemente boa. É provável que volte no futuro de alguma outra forma. (@gaearon em #12820)

React Reconciler (Experimental)