React v16.4.0: события указателя

23 Мая, 2018. Andrew Clark (Эндрю Кларк)

Последний релиз добавляет поддержку часто запрашиваемой функции: события указателя!

Он также включает исправление багов для getDerivedStateFromProps. Ознакомьтесь с полным списком изменений ниже.


События указателя

В React DOM теперь доступны следующие типы событий:

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

Обратите внимание, что данные события будут работать только в браузерах, поддерживающих спецификацию указателя событий . (На момент написания данной статьи, её поддерживают последние версии Chrome, Firefox, Edge и Internet Explorer.) Если ваше приложение зависит от указанных выше событий, мы рекомендуем использовать полифил событий указателя. Мы решили не включать такой полифил в React DOM, чтобы избежать увеличения размера пакета.

Ознакомьтесь с данным примером в CodeSandbox.

Огромное спасибо Филиппу Списсу за содействие!


Исправление багов, связанных с getDerivedStateFromProps

getDerivedStateFromProps теперь вызывается каждый раз, когда отрисовывается компонент, независимо от причины обновления. Раньше он вызывался только в том случае, если компонент был повторно отрисован его родителем и не срабатывал в результате вызова setState. Это был дефект в первоначальной реализации, который теперь исправлен. Предыдущее поведение было больше похоже на componentWillReceiveProps, тогда как улучшенное поведение обеспечивает совместимость с предстоящим асинхронным режимом отрисовки React.

Данное исправление исправление дефекта не повлияет на большинство приложений, но может вызвать проблемы в небольшом множестве компонентов. Редкие случаи, когда это имеет значение, относятся к одной из двух категорий:


1. Избежание побочных эффектов в getDerivedStateFromProps

Как и метод render, getDerivedStateFromProps должен быть чистой функцией props и state. Побочные эффекты в getDerivedStateFromProps никогда не поддерживались, но поскольку он теперь срабатывает чаще, недавнее исправление может выявить ранее не обнаруженные ошибки.

Код с побочными эффектами следует перенести в другие методы: например, диспетчеры Flux обычно располагаются в обработчике происходящего события, а ручные DOM-мутации находятся внутри componentDidMount или componentDidUpdate. Об этом вы можете прочитать в нашей недавней публикации о подготовке к асинхронной отрисовке.


2. Сравнение приходящих свойств с предыдущими свойствами во время вычисления контролируемых значений

Следующий код предполагает, что getDerivedStateFromProps срабатывает только тогда, когда изменяются свойства:


Код
    
  static getDerivedStateFromProps(props, state) {
    if (props.value !== state.controlledValue) {
      return {
        // Так как метод срабатывает при изменениях и props, и state, локальные обновления
        // в контролируемом значении будут проигнорированы, так как версия props
        // всегда переопределяет его. Упс!
        controlledValue: props.value,
      };
    }
    return null;
  }
  

Один из возможных способов исправить это - сравнить входящее значение с предыдущим значением, путем сохранения предыдущих свойств в состояние:


Код
    
  static getDerivedStateFromProps(props, state) {
    const prevProps = state.prevProps;
    // Сравнение входящего свойства с предыдущим
    const controlledValue =
      prevProps.value !== props.value
        ? props.value
        : state.controlledValue;
    return {
      // Сохранение предыдущих свойств в состояние
      prevProps: props,
      controlledValue,
    };
  }
  

Тем не менее старайтесь избегать смешивания свойств и состояния подобным образом. Редко случается ситуация, в которой состояние должно дублировать значение, существующее в свойствах. Это может привести к трудно обнаружимым ошибкам. Предпочитайте иметь один достоверный источник для любого значения и, при необходимости, поднимать состояние, чтобы использовать его совместно между несколькими компонентами. В большинстве случаев от применения getDerivedStateFromProps (и его предшественника componentWillReceiveProps) можно избавиться, перемещая управление состоянием в родительский компонент.

Помните, что большинство компонентов не нуждаются в getDerivedStateFromProps. Он не предназначен для использования точь в точь, как componentWillReceiveProps. В ближайшие недели мы выпустим последующую публикацию с дополнительными рекомендациями о том, как использовать (и не использовать) getDerivedStateFromProps.


Установка

React v16.4.0 доступен в реестре npm.

Чтобы установить React 16 с помощью Yarn, выполните:


Код
    
  yarn add [email protected]^16.4.0 [email protected]^16.4.0
  

Чтобы установить React 16 с помощью npm, выполните:


Код
    
  npm install --save [email protected]^16.4.0 [email protected]^16.4.0
  

Мы также предоставляем UMD-сборки React в CDN:


Код
    
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
  

Подробные инструкции по установке см. в документации .


Лог изменений


React

  • Добавлен новый экспериментальный React.unstable_Profiler компонент для измерения производительности.( #12745 )


React DOM

  • Добавлена поддержка спецификации событий указателя.( #12745 )
  • Правильный вызов getDerivedStateFromProps() независимо от причины переотрисовки. ( #12600 и #12802 )
  • Исправлен баг, который в некоторых случаях предотвращал распространение(propagation) контекста. ( #12708 )
  • Исправлена перерисовка компонентов, использующих forwardRef() на более глубоком setState(). ( #12690 )
  • Исправлены некоторые атрибуты, которые неправильно удалялись из пользовательских элементов-узлов. ( #12702 )
  • Исправлены поставщики контекста, чтобы не оставить без внимания потомков, если выше используется устаревший поставщик контекста. ( #12586 )
  • Добавлена возможность указать propTypes в компоненте поставщика контекста. ( #12658 )
  • Исправлено ложное положительное предупреждение при использовании react-lifecycles-compat в <StrictMode>.( #12644 )
  • Добавлено предупреждение, когда функция renderRef() имеет propTypes или defaultProps. ( #12644 )
  • Улучшено отображение потребителей forwardRef() и контекста в стеке компонентов. ( #12777 )
  • Изменение имен внутренних событий. Это может поломать сторонние пакеты, которые полагаются на внутреннюю реализацию React неподдерживаемыми способами.( #12629 )


Тестовый отрисовщик React (React Test Renderer)

  • Исправлена поддержка getDerivedStateFromProps(), для соответствия новому поведению React DOM. ( #12676 )
  • Исправлен крэш testInstance.parent, когда родителем является фрагментом или другим специальным узлом. ( #12813 )
  • Компоненты forwardRef() теперь можно обнаружить с помощью методов обхода из модуля тестовой отрисовки. ( #12725 )
  • Неглубокий рендеринг теперь игнорирует функции обновления метода setState(), которые возвращают значение null или undefined. ( #12756 )


React ART

  • Исправлен контекст чтения, предоставляемый деревом, управляемым React DOM. ( #12779 )


React Call Return (Экспериментальный)

  • Этот эксперимент был удален, поскольку он влиял на размер пакета и API получился недостаточно хорош. Вероятно, в будущем он вернется в какой-либо другой форме. ( #12820 )


React Reconciler (Экспериментальный)