Мы рады представить вам наш первый релиз-кандидат версии 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

Комментарии (5)


  1. mwizard
    12.09.2015 03:25
    -20

    Мы рекомендуем использовать React через npm
    На этом месте я очень сильно удивился, и перечитал статью сначала. Ну да, речь о React.js, а не о ReactOS.


    1. MaximChistov
      12.09.2015 10:03
      +1

      что указано в хабах =)


  1. webMarshal
    12.09.2015 12:26

    Для предупреждений React теперь использует console.error вместо console.warn

    Теперь полная консоль ошибок будет


    1. Kalifriki
      12.09.2015 19:30

      А вы что, предупреждения не исправляете? :)


      1. webMarshal
        13.09.2015 09:31

        Звучит не очень, но есть грешок… Когда рендеришь что-то необычное, типа карты (leaflet, google) то делаешь это только на клиенте и дом после клиентского рендера, как правило разнится с серверным — это пример такого долгого ворнинга в консоли, ну а если там key не хватает в массиве или по каким-то другим причинам дом после рендеров разнится, то, конечно, стараемся исправлять. Тимлид зверь.