Skip to content

Latest commit

 

History

History
171 lines (115 loc) · 15 KB

File metadata and controls

171 lines (115 loc) · 15 KB
title description
Отличия от React
В чем заключаются различия между Preact и React. В данном документе они подробно описаны

Отличия от React

Preact не претендует на то, чтобы быть повторной реализацией React. Различия есть. Многие из этих различий тривиальны или могут быть полностью устранены с помощью preact/compat, который представляет собой тонкий слой над Preact, пытающийся достичь 100% совместимости с React.

Причина, по которой Preact не пытается включить в себя все возможности React, заключается в том, чтобы оставаться маленьким и сфокусированным — в противном случае было бы разумнее просто направлять оптимизации в проект React, который уже является очень сложной и хорошо структурированной кодовой базой.



Основные отличия

Основное отличие Preact от React заключается в том, что Preact не реализует синтетическую систему событий по соображениям размера и производительности. Для регистрации обработчиков событий в Preact используется стандартная для браузера функция addEventListener, что означает, что именование и поведение событий в Preact работает так же, как и в обычном JavaScript / DOM. Полный список обработчиков событий DOM перечислен в Справочнике по событиям.

Стандартные события браузера работают очень похоже на то, как события работают в React, с небольшими отличиями. В Preact:

  • события не распространяются через компоненты <Portal>.
  • стандартное onInput должно использоваться вместо onChange от React для ввода формы (только если preact/compat не используется)
  • стандартное onDblClick должно использоваться вместо onDoubleClick от React (только если preact/compat не используется)
  • onSearch обычно следует использовать для <input type="search">, поскольку кнопка очистки "x" не активирует onInput в IE11.

Ещё одно заметное отличие заключается в том, что Preact более точно следует спецификации DOM. Пользовательские элементы поддерживаются так же, как и любой другой элемент, а пользовательские события поддерживаются с именами, чувствительными к регистру (как и в DOM).

Совместимость версий

Как для preact, так и для preact/compat совместимость версий измеряется по отношению к текущим и предыдущим основным выпускам React. Когда команда React анонсирует новые функции, они могут быть добавлены в ядро ​​Preact, если это имеет смысл с учетом целей проекта. Это довольно демократичный процесс, постоянно развивающийся посредством дискуссий и решений, принимаемых открыто, с использованием вопросов и запросов на включение.

Таким образом, сайт и документация отражают версии React с 15.x по 17.x, с некоторыми дополнениями из 18.x и 19.x, когда речь идет о совместимости или сравнении.

Отладочные сообщения и ошибки

Наша гибкая архитектура позволяет аддонам улучшать работу Preact любым удобным для них способом. Одним из таких дополнений является preact/debug, который добавляет полезные предупреждения и ошибки и присоединяет Инструменты разработчика Preact, если оответствующее расширение браузера установлено. Они помогут вам при разработке приложений Preact и значительно упрощают проверку того, что происходит. Вы можете включить их, добавив соответствующий оператор импорта:

import 'preact/debug'; // <-- Добавьте эту строку в начало вашего основного файла

Это отличается от React, где требуется наличие сборщика, который удаляет отладочные сообщения во время сборки, проверяя наличие NODE_ENV != "production".

Особенности, присущие только Preact

На самом деле Preact добавляет несколько удобных функций, вдохновленных работой сообщества (P)React:

Встроенная поддержка ES-модулей

Preact с самого начала создавался с учетом ES-модулей и был одним из первых фреймворков, поддерживающих их. Вы можете загружать Preact с помощью ключевого слова import непосредственно в браузерах, не пропуская его через сборщик.

Аргументы в Component.render()

Для удобства мы передаем this.props и this.state в метод render() на компонентах класса. Посмотрите на этот компонент, в котором используется одно свойство prop и одно свойство state.

// Работает как в Preact, так и в React
class Foo extends Component {
  state = { age: 1 };

  render() {
    return (
      <div>
        Имя: {this.props.name}, Возраст: {this.state.age}
      </div>
    );
  }
}

На языке Preact это можно записать и так:

// Работает только в Preact
class Foo extends Component {
  state = { age: 1 };

  render({ name }, { age }) {
    return (
      <div>
        Имя: {name}, Возраст: {age}
      </div>
    );
  }
}

Оба сниппета выводят одно и то же, аргументы render приведены для удобства.

Необработанные имена атрибутов/свойств HTML

Preact стремится максимально соответствовать спецификации DOM, поддерживаемой всеми основными браузерами. Применяя props к элементу, Preact определяет, должен ли каждый prop быть установлен как свойство или как HTML-атрибут. Это позволяет задавать сложные свойства для пользовательских элементов, но также означает, что в JSX можно использовать имена атрибутов типа class:

// Это:
<div class="foo" />

// ...то же самое, что:
<div className="foo" />

Большинство разработчиков Preact предпочитают использовать class вместо className, так как он короче в написании, но поддерживаются оба варианта.

SVG внутри JSX

SVG довольно интересен, когда речь заходит о названиях его свойств и атрибутов. Некоторые свойства (и их атрибуты) объектов SVG имеют верблюжий регистр (например, clipPathUnits на элементе clipPath), некоторые атрибуты имеют шашлычный регистр (например, clip-path во многих SVG-элементах), и другие атрибуты (обычно наследуемые от DOM, например oninput) все строчные.

Preact применяет атрибуты SVG в том виде, в котором они написаны. Это означает, что вы можете копировать и вставлять немодифицированные фрагменты SVG прямо в свой код, и они будут работать «из коробки». Это обеспечивает большую совместимость с инструментами, которые обычно используют дизайнеры для создания пиктограмм или SVG-иллюстраций.

// React
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
  <circle fill="none" strokeWidth="2" strokeLinejoin="round" cx="24" cy="24" r="20" />
</svg>
// Preact (обратите внимание на stroke-width и stroke-linejoin)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
  <circle fill="none" stroke-width="2" stroke-linejoin="round" cx="24" cy="24" r="20" />
</svg>

Если вы пришли из React, то, возможно, привыкли указывать все атрибуты в camelCase. Вы можете продолжать использовать имена SVG-атрибутов всегда с верблюжьим регистром, добавив в свой проект preact/compat, который зеркально отражает API React и нормализует эти атрибуты.

Использование onInput вместо onChange.

Во многом по историческим причинам семантика события React onChange фактически совпадает с событием onInput, предоставляемым браузерами, которое поддерживается повсеместно. Событие input является наиболее подходящим для большинства случаев, когда необходимо реагировать на изменение элемента управления формы. В ядре Preact onChange — это стандартное событие DOM change event, которое срабатывает, когда значение элемента фиксируется пользователем.

// React
<input onChange={e => console.log(e.currentTarget.value)} />

// Preact
<input onInput={e => console.log(e.currentTarget.value)} />

Если вы используете preact/compat, то большинство событий onChange внутренне преобразуются в onInput для эмуляции поведения React. Это один из приемов, который мы используем для обеспечения максимальной совместимости с экосистемой React.

JSX-конструктор

JSX — это расширение синтаксиса JavaScript, которое преобразуется во вложенные вызовы функций. Идея использования вложенных вызовов для построения древовидных структур возникла задолго до появления JSX, а ранее была популяризирована в JavaScript проектом hyperscript. Этот подход имеет ценность далеко за пределами экосистемы React, поэтому Preact продвигает оригинальный обобщенный комьюнити-стандарт. Для более подробного обсуждения JSX и его связи с Hyperscript прочитайте эту статью о том, как работает JSX.

Исходник: (JSX)

<a href='/'>
  <span>Главная</span>
</a>

Вывод:

// Preact:
h('a', { href: '/' }, h('span', null, 'Главная'));

// React:
React.createElement('a', { href: '/' }, React.createElement('span', null, 'Главная'));

В конечном итоге, если посмотреть на сгенерированный выходной код приложения Preact, то становится ясно, что более короткая «JSX pragma» без переноса имён легче читается и более пригодна для оптимизации, например, минификации. В большинстве приложений Preact вы встретите h(), хотя на самом деле не имеет значения, какое имя вы используете, поскольку также предусмотрен экспорт псевдонима createElement.

contextTypes не нужен

Устаревший API Context требует, чтобы компоненты объявляли определённые свойства, используя contextTypes или childContextTypes React, чтобы получить эти значения. У Preact нет этого требования: все компоненты по умолчанию получают все свойства context, созданные getChildContext().