Мы рады представить вам наш первый релиз-кандидат версии React 0.14! Мы опубликовали в июле анонс предстоящих изменениях, но сейчас мы еще больше стабилизировали релиз и нам бы хотелось, чтобы вы попробовали его до того, как мы выпустим финальную версию.

Сообщите нам, если у вас возникли любые проблемы, создав задачу в нашем GitHub репозитории


Инсталляция


Мы рекомендуем использовать React через npm и использовать утилиты, типа browserify или webpack для сборки вашего кода в один пакет:

npm install --save react@0.14.0-rc1
npm install --save react-dom@0.14.0-rc1

Помните, что по умолчанию, в режиме разработки React запускает дополнительные проверки и предоставляет полезные предупреждения. Поэтому, при развертывания вашего приложения установите переменную окружения NODE_ENV в production для использования production-режима, при котором React не включает служебные предупреждения и работает значительно быстрее.

Если вы не можете использовать npm, мы также предоставляем скомпилированные сборки для браузеров для вашего удобства:


Эти сборки также доступны в качестве bower-пакетов: react и react-dom

Основные изменения



Два пакета: React и React DOM


Когда мы смотрим на такие модули, как react-native, react-art, react-canvas и react-three, становится понятно, что красота и сущность React не имеет ничего общего с браузерами или DOM.

Чтобы сделать это более прозрачным и проще для использования в большем количестве окружений, где React может рендерить, мы разделили главный пакет react на два: react и react-dom.
Это открывает путь для написания компонентов, которые могут совместно использоваться в веб-версиях React и React Native. Мы не предполагаем, что весь код в приложении должен быть расшарен, но мы хотим иметь возможность совместного использования компонентов, которые ведут себя одинаково на разных платформах.

Пакет react содержит React.createElement, .createClass, .Component, .PropTypes, .Children и другие хелперы ориентированные на элементы и компонентные классы. Мы думаем о них, как о изоморфных или универсальных хелперах, которые необходимы вам для построения компонентов.

Пакет react-dom содержит ReactDOM.render, .unmountComponentAtNode и .findDOMNode. В react-dom/server у нас есть поддержка рендера на сервере при помощи ReactDOMServer.renderToString и .renderToStaticMarkup.

var React = require('react');
var ReactDOM = require('react-dom');</p>

<p>var MyComponent = React.createClass({
  render: function() {
    return <div>Hello World</div>;
  }
});

ReactDOM.render(<MyComponent />, node);


Мы опубликовали автоматизированный codemod скрипт, который мы используем в Facebook для этого перехода

Дополнения (Add-ons) были перемещены в отдельные пакеты: react-addons-clone-with-props, react-addons-create-fragment, react-addons-css-transition-group, react-addons-linked-state-mixin, react-addons-perf, react-addons-pure-render-mixin, react-addons-shallow-compare, react-addons-test-utils, react-addons-transition-group и react-addons-update, а также ReactDOM.unstable_batchedUpdates в react-dom

На данный момент, используйте пожалуйста определенные версии react и react-dom в ваших приложениях, для предотвращения проблем с версионностью.

Ссылки на DOM узлы


Другим важным изменением, которое мы сделали в этом релизе является то, что ссылки (refs) на компоненты DOM, теперь ссылаются на сам DOM узел.
Что это значит: мы посмотрели на то, что вы делаете с ссылкой (ref) на React DOM компоненты и поняли, что единственная полезная вещь, которую вы можете сделать с ним — это вызов this.refs.giraffe.getDOMNode() для получения DOM узла. В этом релизе, this.refs.giraffe это текущая DOM нода.
Обратите внимание, что ссылки на кастомные (заданные пользователем) компоненты, работают также, как и раньше; только нативные DOM компоненты подпадают под это изменение.

var Zoo = React.createClass({
  render: function() {
    return <div>Giraffe name: <input ref="giraffe" /></div>;
  },
  showName: function() {
    // Previously: var input = this.refs.giraffe.getDOMNode();
    var input = this.refs.giraffe;
    alert(input.value);
  }
});


Это изменение также относится и к возвращаемому результату ReactDOM.render когда мы передаем DOM узел, как корневой компонент. Как и в случаи с refs, эти изменения не распространяются на кастомные компоненты. C этими изменениями, мы объявляем метод .getDOMNode() неподдерживаемым и заменяем его методом ReactDOM.findDOMNode (см. далее).

«Глупые» компоненты


В характерном для React коде, большинство компонентов, которые вы пишете, не должны иметь собственного состояния, т.н. stateless. Мы представляем новый, более простой синтаксис для таких компонентов, в котором вы можете передать props, как аргумент и вернуть элемент, который вы хотите отрисовать:

// Используя ES2015 (ES6) стрелочную функцию:
var Aquarium = (props) => {
  var fish = getFish(props.species);
  return <Tank>{fish}</Tank>;
};

// Или с деструкцией и неявным возвращением:
var Aquarium = ({species}) => (
  <Tank>
    {getFish(species)}
  </Tank>
);

// Далее используем: <Aquarium species="rainbowfish" />


Этот паттерн создан для поощрения создания этих простых компонентов, которые должны составить большую часть ваших приложений. В будущем, мы также сможем оптимизировать производительность, конкретно для этих компонентов, избегая ненужных проверок и распределения памяти.

React-tools больше не поддерживается


Пакет react-tools и браузерный вариант JSXTransformer.js — нежелательны к применению. Вы можете продолжить их использование в версии 0.13.3, но мы больше их не поддерживаем и рекомендуем перейти на использование Babel, который имеет встроенную поддержку React и JSX.

Оптимизация компилятора


React теперь поддерживает две оптимизации компилятора, которые могут быть включены в Babel 5.8.23 и выше. Обе эти трансформации должны быть включены только в продакшене (например, до минификации) потому что хотя они и улучшают производительность выполнения, но делают служебные предупреждения более скрытыми и пропускают важные проверки, которые происходят в режиме разработки, в том числе propTypes.

Встраивание React элементов: optimisation.react.inlineElements конвертирует JSX элементы в объекты, типа {type: 'div', props: ...} вместо вызова React.createElement.

Постоянное «всплытие» React элементов: optimisation.react.constantElements «поднимает» создание элементов на верхний уровень поддеревьев, который полностью статичен, что уменьшает вызовы React.createElement и перемещения. Важнее то, что это информирует React, что поддерево не изменилось, поэтому React может полностью пропустить его при согласовании.

Критические изменения


Как обычно, у нас есть несколько критических изменений в этом релизе. Всякий раз, когда мы вносим большие изменения, мы предупреждаем, как минимум за один релиз, т.ч. у вас есть время обновить ваш код. Кодовая база Facebook составляет более 15,000 React компонентов, поэтому в команде React, мы всегда стараемся свести к минимуму последствия от критических изменений.

Эти три критические изменения выводили предупреждения в версии 0.13, поэтому вам нет необходимости что-то делать, если в вашем коде нет предупреждений:
  • Объект props теперь фиксирован, поэтому изменение props после создания компонента больше не поддерживается. В большинстве случае, взамен необходимо использовать React.cloneElement. Эти изменения делают ваши компоненты более легкими для понимания и включают оптимизацию компиляции, описанную выше.
  • Простые объекты больше не поддерживаются в качестве потомков React, вместо этого вы должны использовать массивы. Вы можете использовать хелпер createFragment для миграции, который сейчас возвращает массив.
  • Add-Ons: classSet был удален. Вместо этого используйте classnames


А эти два изменения не диагностировались в 0.13, но их легко будет найти и исправить:
  • React.initializeTouchEvents больше не нужно и может быть полностью удалено. Тач-эвенты теперь работают автоматически.
  • Add-Ons: В связи с тем, что ссылки на DOM ноды изменились, как упоминалось выше, TestUtils.findAllInRenderedTree и связанные с ним хелперы больше недоступны для получения DOM компонентов, а только для кастомных компонентов.


Новые исключения, выводимые в предупреждениях


  • В связи с тем, что ссылки на DOM ноды изменились, как упоминалось выше, this.getDOMNode() теперь исключен и взамен вы можете использовать ReactDOM.findDOMNode(this). Заметьте, что в большинстве случаев, вызов findDOMNode теперь не нужен – смотрите пример указанный выше в секции “Ссылки на DOM узлы".

    Если у вас большая кодовая база, вы можете использовать наш automated codemod script для автоматического исправления вашего кода.
  • setProps и replaceProps теперь запрещены. Вместо этого снова вызовите ReactDOM.render на верхнем уровне с новыми props.
  • Классы компонентов ES6 теперь должны расширить React.Component надлежащим образом для поддержки «глупых» компонентов. Шаблон ES3 модуля продолжает работать.
  • Переиспользование и изменение style объекта между рендерами теперь запрещена. Это отражает суть нашего изменения, заморозить props объекта.
  • Add-Ons: cloneWithProps теперь запрещено. Взамен используйте React.cloneElement (в отличии от cloneWithProps, cloneElement не объединяет className или style автоматически, вы можете объединять их вручную, если надо).
  • Add-Ons: Для повышения надежности, CSSTransitionGroup больше не будет слушать transition события. Вместо этого, вы должны вручную устанавливать продолжительность transition используя свойства, такие как transitionEnterTimeout={500}.


Значимые улучшения


  • Добавлен React.Children.toArray который берет объект вложенных потомков и возвращает плоский массив с ключами, назначаемые каждому ребенку. Этот хелпер упрощает управление коллекциями детей в ваших render методах, особенно, если вы хотите перераспределить или извлечь this.props.children перед передачей их далее. В дополнение, React.Children.map также теперь возвращает простой массив.
  • Для предупреждений React теперь использует console.error вместо console.warn, т.ч. браузеры показывают полный стек в консоли. (Наши предупреждения появляются при использовании шаблонов, которые будут изменены в будущих версиях и для кода, который, скорее всего, ведет себя неожиданно, поэтому мы считаем, что наши предупреждения должны быть «must-fix» ошибками.)
  • Ранее, использование ненадежных объектов, в качестве React потомков могло привести к XSS-уязвимости. Эта проблема должна быть должным образом исключена, путем валидирования входа на уровне приложений и не использования ненадежных объектов по всему коду приложения. В качестве дополнительного уровня защиты, React теперь помечает элементы определенным ES2015 (ES6) типом Symbol, в браузерах, которые его поддерживают, для того, чтобы гарантировать, что React никогда не посчитает ненадежный JSON вал��дным элементом. Если это дополнительная защита безопасности является важной для вас, вы должны добавить Symbol полифил для старых браузеров, например Babel’s polyfill.
  • Когда это возможно, React DOM теперь генерирует XHTML-совместимую разметку.
  • React DOM теперь поддерживает такие стандартные HTML атрибуты: capture, challenge, inputMode, is, keyParams, keyType, minLength, summary, wrap. Он также теперь поддерживает и эти нестандартные атрибуты: autoSave, results, security.
  • React DOM теперь поддерживает следующие SVG атрибуты, которые могут рендерится в namespaced атрибуты: xlinkActuate, xlinkArcrole, xlinkHref, xlinkRole, xlinkShow, xlinkTitle, xlinkType, xmlBase, xmlLang, xmlSpace.
  • SVG тэг image теперь поддерживается в React DOM.
  • В React DOM, произвольные атрибуты поддерживаются на пользовательских элеменах (тех, с дефисом в имени тега или атрибутом is="...").
  • React DOM теперь поддерживает следующие медиа-события на audio и video тэгах: onAbort, onCanPlay, onCanPlayThrough, onDurationChange, onEmptied, onEncrypted, onEnded, onError, onLoadedData, onLoadedMetadata, onLoadStart, onPause, onPlay, onPlaying, onProgress, onRateChange, onSeeked, onSeeking, onStalled, onSuspend, onTimeUpdate, onVolumeChange, onWaiting.
  • Было сделано множество небольших улучшений производительности.
  • Многие предупреждения показывают больше информации, чем раньше.
  • Add-Ons: Дополнение shallowCompare было добавлено в качестве пути миграции для PureRenderMixin для ES6 классов.
  • Add-Ons: CSSTransitionGroup может теперь использовать произвольные имена классов вместо добавления -enter-active или схожего с именем transition.


Новые полезные предупреждения


  • React DOM теперь предупреждает вас, когда вложенные HTML элементы невалидны, что помогает вам избежать удивительных ошибок во время обновления.
  • Подключение document.body напрямую в качестве контейнера для ReactDOM.render теперь выдает предупреждение, т.к. это может вызывать проблемы с расширениями браузера, которые изменяют DOM.
  • Совместное использование нескольких инстансов React не поддерживается, поэтому мы теперь выводим предупреждение, когда обнаруживаем этот случай, чтобы помочь вам избежать проблем.


Значимые исправления


  • Click-события обрабатываются React DOM более надежно в мобильных браузерах, в частности в Mobile Safari.
  • SVG элементы создаются с правильными неймспейсами в большинстве случаев.
  • React DOM теперь правильно рендерит <option> элементы с несколькими текстовыми детьми и рендерит <select> элементы на сервере, с правильно выбранной опцией.
  • Когда два отдельных экземпляра React добавляют узлы в один и тот же документ (в том числе, когда расширение для браузера использует React), React DOM упорно пытается не бросать исключения во время обработки событий.
  • Использование HTML тэгов не в нижнем регистре в React DOM (например, React.createElement('DIV')) теперь не вызывает проблем, однако мы продолжаем рекомендовать использование нижнего регистра для соответствия с конвенцией наименования JSX тэгов (нижний регистр для встроенных компонентов, заглавное наименование для кастомных компонентов).
  • React DOM понимает, что эти свойства CSS являются безразмерными и не добавляет «px» для их значений: animationIterationCount, boxOrdinalGroup, flexOrder, tabSize, stopOpacity.
  • Add-Ons: При использовании тестовых утилит, Simulate.mouseEnter и Simulate.mouseLeave теперь работает
  • Add-Ons: ReactTransitionGroup теперь корректно обрабатывает множественные узлы, удаляя одновременно.


Автор: Ben Alpert