Мы рады представить вам наш первый релиз-кандидат версии React 0.14! Мы опубликовали в июле анонс предстоящих изменениях, но сейчас мы еще больше стабилизировали релиз и нам бы хотелось, чтобы вы попробовали его до того, как мы выпустим финальную версию.
Сообщите нам, если у вас возникли любые проблемы, создав задачу в нашем GitHub репозитории
Мы рекомендуем использовать React через npm и использовать утилиты, типа browserify или webpack для сборки вашего кода в один пакет:
Помните, что по умолчанию, в режиме разработки React запускает дополнительные проверки и предоставляет полезные предупреждения. Поэтому, при развертывания вашего приложения установите переменную окружения NODE_ENV в production для использования production-режима, при котором React не включает служебные предупреждения и работает значительно быстрее.
Если вы не можете использовать npm, мы также предоставляем скомпилированные сборки для браузеров для вашего удобства:
Эти сборки также доступны в качестве bower-пакетов: 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.
Мы опубликовали автоматизированный 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 в ваших приложениях, для предотвращения проблем с версионностью.
Другим важным изменением, которое мы сделали в этом релизе является то, что ссылки (refs) на компоненты DOM, теперь ссылаются на сам DOM узел.
Что это значит: мы посмотрели на то, что вы делаете с ссылкой (ref) на React DOM компоненты и поняли, что единственная полезная вещь, которую вы можете сделать с ним — это вызов this.refs.giraffe.getDOMNode() для получения DOM узла. В этом релизе, this.refs.giraffe это текущая DOM нода.
Обратите внимание, что ссылки на кастомные (заданные пользователем) компоненты, работают также, как и раньше; только нативные DOM компоненты подпадают под это изменение.
Это изменение также относится и к возвращаемому результату ReactDOM.render когда мы передаем DOM узел, как корневой компонент. Как и в случаи с refs, эти изменения не распространяются на кастомные компоненты. C этими изменениями, мы объявляем метод .getDOMNode() неподдерживаемым и заменяем его методом ReactDOM.findDOMNode (см. далее).
В характерном для React коде, большинство компонентов, которые вы пишете, не должны иметь собственного состояния, т.н. stateless. Мы представляем новый, более простой синтаксис для таких компонентов, в котором вы можете передать props, как аргумент и вернуть элемент, который вы хотите отрисовать:
Этот паттерн создан для поощрения создания этих простых компонентов, которые должны составить большую часть ваших приложений. В будущем, мы также сможем оптимизировать производительность, конкретно для этих компонентов, избегая ненужных проверок и распределения памяти.
Пакет 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, поэтому вам нет необходимости что-то делать, если в вашем коде нет предупреждений:
А эти два изменения не диагностировались в 0.13, но их легко будет найти и исправить:
Автор: Ben Alpert
Сообщите нам, если у вас возникли любые проблемы, создав задачу в нашем 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, мы также предоставляем скомпилированные сборки для браузеров для вашего удобства:
- React
Dev-сборка с предупреждениями: https://fb.me/react-0.14.0-rc1.js
Минифицированная production-сборка: https://fb.me/react-0.14.0-rc1.min.js - React с Add-Ons
Dev-сборка с предупреждениями: https://fb.me/react-with-addons-0.14.0-rc1.js
Dev-сборка с предупреждениями: https://fb.me/react-with-addons-0.14.0-rc1.min.js - React DOM (подключайте React на странице до React DOM)
Dev-сборка с предупреждениями: https://fb.me/react-dom-0.14.0-rc1.js
Dev-сборка с предупреждениями: https://fb.me/react-dom-0.14.0-rc1.min.js
Эти сборки также доступны в качестве 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