React: React Fire: Модернизация React DOM

Созданный на 31 авг. 2018  ·  227Комментарии  ·  Источник: facebook/react


Последний статус см. в обновлении от 5 июня 2019 г.: https://github.com/facebook/react/issues/13525#issuecomment -499196939.


В этом году команда React в основном сосредоточилась на фундаментальных улучшениях React .

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

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

Мы называем это усилие «React Fire».

🔥 Реагировать на огонь

React Fire — это попытка модернизировать React DOM. Наша цель — сделать React более согласованным с тем, как работает DOM, пересмотреть некоторые противоречивые прошлые решения, которые привели к проблемам, и сделать React меньше и быстрее.

Мы хотим добавить этот набор изменений в будущий основной выпуск React, потому что некоторые из них, к сожалению, не работают. Тем не менее, мы считаем, что они того стоят. И у нас есть более 50 тысяч компонентов в Facebook, чтобы мы оставались честными в отношении нашей стратегии миграции. Мы не можем позволить себе переписывать код продукта, за исключением нескольких целевых исправлений или автоматических модификаций кода.

Стратегия

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

  • Перестаньте отражать входные значения в атрибуте value (https://github.com/facebook/react/issues/11896). Первоначально это было добавлено в React 15.2.0 через https://github.com/facebook/react/pull/6406. Это очень часто запрашивалось, потому что концептуальная модель модели DOM состоит в том, что value , которую они видят в инспекторе DOM, должен соответствовать атрибуту JSX value . Но это не то, как работает DOM. Когда вы вводите в поле, браузер не обновляет атрибут value . Реакция тоже не должна этого делать. Оказалось, что это изменение, возможно, полезное для некоторого кода, основанного на селекторах CSS, вызвало каскад ошибок — некоторые из них до сих пор не исправлены. Некоторые последствия этого изменения включают: https://github.com/facebook/react/issues/7179 , https://github.com/facebook/react/issues/8395 , https://github.com/facebook . https://github.com/facebook/react/issues/7233 , https://github.com/facebook/react/issues/11881 , https://github.com/facebook/react /issues/7253 , https://github.com/facebook/react/pull/9584 , https://github.com/facebook/react/pull/9806 , https://github.com/facebook/react/pull /9714 , https://github.com/facebook/react/pull/11534 , https://github.com/facebook/react/pull/11746 , https://github.com/facebook/react/pull/12925 . На данный момент явно не стоит продолжать бороться с браузером, и мы должны отменить его. Положительной стороной этого путешествия является то, что благодаря неустанной работе наших участников DOM ( @nhunzaker , @aweary , @jquense и @philipp-spiess ) у нас теперь есть подробные тестовые приборы DOM, которые помогут нам избежать регрессий.

  • Прикрепляйте события к корню React, а не к документу (https://github.com/facebook/react/issues/2043). Присоединение обработчиков событий к документу становится проблемой при встраивании приложений React в более крупные системы. Редактор Atom был одним из первых, кто столкнулся с этим. На любом крупном веб-сайте рано или поздно возникают очень сложные пограничные случаи, связанные с stopPropagation , взаимодействующими с кодом, отличным от React, или с корнями React (https://github.com/facebook/react/issues/8693, https://github). .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). Мы также хотим с готовностью привязывать события к каждому корню, чтобы мы могли выполнять меньше проверок во время выполнения во время обновлений.

  • Перейдите с onChange на onInput и не используйте полифиллы для неконтролируемых компонентов (https://github.com/facebook/react/issues/9657). Подробный план см. в связанной проблеме. Сбивает с толку то, что React использует другое имя события для того, что известно как событие input в DOM. Хотя обычно мы избегаем таких больших изменений без существенной выгоды, в данном случае мы также хотим изменить поведение, чтобы устранить некоторую сложность, которая необходима только для крайних случаев, таких как изменение контролируемых входных данных. Поэтому имеет смысл сделать эти два изменения вместе и использовать это как возможность заставить onInput и onChange работать точно так же, как события DOM работают для неконтролируемых компонентов.

  • Кардинально упростить систему событий (https://github.com/facebook/react/issues/4751). Текущая система событий почти не изменилась с момента ее первоначальной реализации в 2013 году. Она повторно используется в React DOM и React Native, поэтому она излишне абстрактна. Многие полифилы, которые он предоставляет, не нужны современным браузерам, а некоторые из них создают больше проблем, чем решают. На него также приходится значительная часть размера пакета React DOM. У нас нет конкретного плана, но мы, вероятно, полностью разветвим систему событий, а затем посмотрим, насколько минимальной мы сможем ее сделать, если будем придерживаться того, что дает нам DOM. Вполне вероятно, что мы вообще избавимся от синтетических событий. Мы должны прекратить всплывать события, такие как медиа-события, которые не всплывают в DOM и не имеют веской причины всплывать. Мы хотим сохранить некоторые специфичные для React возможности, такие как всплывающее окно через порталы, но мы попытаемся сделать это с помощью более простых средств (например, повторной отправки события). Пассивные события, вероятно, будут частью этого.

  • classNameclass (https://github.com/facebook/react/issues/4331, см. также https://github.com/facebook/react/issues/13525#issuecomment- 417818906 ниже). Это предлагалось бесчисленное количество раз. Мы уже разрешаем передачу class вниз узлу DOM в React 16. Путаница, которую это создает, не стоит синтаксических ограничений, от которых он пытается защититься. Мы бы не стали делать это изменение само по себе, но в сочетании со всем остальным, что выше, оно имеет смысл. Обратите внимание, что мы не можем просто разрешить и то, и другое без предупреждений, потому что это очень затрудняет обработку компонентной экосистемы. Каждый компонент должен научиться правильно обрабатывать оба компонента, и существует риск их конфликта. Поскольку многие компоненты обрабатывают className (например, добавляя к нему), это слишком подвержено ошибкам.

Компромиссы

  • Мы не можем внести некоторые из этих изменений, если хотим и дальше предоставлять текущие частные API-интерфейсы системы событий React для таких проектов, как React Native Web. Однако для React Native Web в любом случае потребуется другая стратегия, потому что React Fabric , скорее всего, переместит большую часть ответной системы на нативную сторону.

  • Возможно, нам придется отказаться от совместимости с некоторыми старыми браузерами и/или потребовать для них больше автономных полифиллов. Мы по-прежнему заботимся о поддержке IE11, но, возможно, мы не будем пытаться сгладить некоторые из существующих различий между браузерами — такова позиция многих современных UI-библиотек.

План развертывания

На данном этапе проект очень исследовательский. Мы не знаем наверняка, сработает ли все вышеперечисленное. Поскольку изменения значительны, нам нужно протестировать их в Facebook и постепенно опробовать. Это означает, что мы введем флаг функции, разветвим часть кода и оставим его включенным в Facebook для небольшой группы людей. Релизы 16.x с открытым исходным кодом сохранят старое поведение, но на мастере вы сможете запустить его с включенным флагом функции.

Я планирую работать над проектом по большей части сам, но я был бы очень признателен за дальнейшее обсуждение и вклад @nhunzaker , @aweary , @jquense и @philipp-spies, которые были звездными сотрудниками и в значительной степени руководили React DOM в то время. мы работали над оптоволокном. Если есть какая-то область, которая вас особенно интересует, пожалуйста, дайте мне знать, и мы с ней разберемся.

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

DOM React Core Team Big Picture

Самый полезный комментарий

Мне нравится каждый из этих пунктов, кроме изменения className . Это кажется совершенно противоречащим цели, которую преследуют другие точки (согласование с DOM API). React привязывается к свойствам DOM, а не атрибутам HTML (это даже сформулировано в первом пункте). Свойство элемента DOM называется className , а не class . Так почему же в React он называется class ?

Все 227 Комментарий

Мне это нравится. Уменьшение размера пакета и поддержка «класса» — это изменения, которые будут очень кстати.

Отличная работа!

🙂

Вниманию авторов библиотеки форм! 🤣

Здорово!

className → класс фантастический

А как насчет всех остальных? Кажется странным до сих пор делать clipPath , htmlFor , tabIndex и т. д.

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

Это круто. Мне так любопытно, как переход к class на самом деле работает с реквизитом.

Похоже, ({ class }) => <div class={class} /> изначально представляло проблему с зарезервированным ключевым словом?

Это фантастическая новость, спасибо @gaearon!

Мне нравится каждый из этих пунктов, кроме изменения className . Это кажется совершенно противоречащим цели, которую преследуют другие точки (согласование с DOM API). React привязывается к свойствам DOM, а не атрибутам HTML (это даже сформулировано в первом пункте). Свойство элемента DOM называется className , а не class . Так почему же в React он называется class ?

Фантастический! Есть ли у вас цель уменьшить размер пакета?

👏

А как насчет всех остальных? Кажется странным все еще использовать clipPath, htmlFor, tabIndex и т. д.

Я открыт для обсуждения, но я бы сказал, что эти изменения того не стоят (за исключением, может быть, for ).

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

Давай сделаем это!

Интересно, стоит ли одновременно работать над выпуском JSX 2.0 ? Людям в любом случае придется переучиваться некоторым вещам. Может быть, лучше переучить кучу вещей за один раз, чем несколько вещей дважды за определенный период времени? Просто мысль, которая возникла, пока я читал это.

Мне нравится каждый из этих пунктов, кроме изменения className. Это кажется совершенно противоречащим цели, которую преследуют другие точки (согласование с DOM API). React привязывается к свойствам DOM, а не атрибутам HTML (это даже сформулировано в первом пункте).

И все же, если мы передадим неизвестную пару ключ/значение, она будет рассматриваться как атрибут, начиная с React 16. Так что мы уже несовместимы. Кроме того, мой комментарий был о том, что пользователи ошибались, ожидая, что React установит атрибут value . Независимо от того, использует ли React API имя атрибута или имя свойства в своем API, это полностью ортогонально.

Я защищал вашу сторону этого аргумента в течение многих лет, но теперь я думаю, что это трение, которое того не стоит. Вы ничего не получаете от этого. Просто позволение людям использовать class не имеет негативных последствий, за исключением того, что это не работает с деструктурированием и затратами на миграцию. Все жалуются на это, когда изучают React. Я думаю, что делать то, что люди ожидают, в этом случае важнее, чем быть педантичным. И так как мы все равно меняем другие вещи DOM, давайте объединим это вместе.

Пока React Fire кипит быстро.... 👍

Все эти изменения фантастические. Я очень взволнован этим и его последствиями для react-testing-library . В частности, события привязываются к корню реакции (или, может быть, даже полностью отбрасывают делегирование событий, поскольку в современных средах это может больше не понадобиться?), потенциально удаляя/переписывая синтетические события и onChange -> onInput серьезно улучшит реализацию react-testing-library и опыт использования инструмента.

Я хотел бы оставить отзыв об этом, как это реализуется.

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

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

@tannerlinsley ({ class: className }) => <div class={className} /> , к сожалению, это убьет краткое обозначение объекта jsx 2.0 ( <div class /> ), но так тому и быть ...

Было бы супер-прекрасно, если бы class наконец-то могли брать объекты и массивы между строками.

Есть ли у вас цель уменьшить размер пакета?

Было бы неплохо отказаться от трети React DOM. Посмотрим. Трудно сказать заранее, но мы сделаем все возможное.

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

Нравится направление, в котором это происходит.

Каким будет путь обновления для библиотек, которые используют className и хотят поддерживать несколько версий React?

@gaearon Может быть, это не имеет большого значения, сегодня приятно сказать, что «реквизиты - это свойства DOM, а не атрибуты HTML», теперь это будет «кроме className, это имя HTML». Я также хотел бы иметь возможность копировать/вставлять SVG без 10 минут возни с атрибутами, чтобы они соответствовали React

А как насчет htmlFor ?

Такое ощущение, что переход className -> class нужно будет делать очень осторожно, возможно, в течение длительного периода времени. Это вызовет много проблем для экосистемы, так как потребуется изменить практически каждый компонент, даже самый незначительный. В основном это нормально, если вы «владеете» кодом и есть codemod, но когда вы зависите от сторонних библиотек, вы в значительной степени зависите от сопровождающих.

Остальные изменения кажутся относительно низким риском с точки зрения экосистемы, но избавление от className действительно вызовет много боли. Кажется, можно было бы выделить это в отдельный выпуск и выпустить по графику, отличному от остальных 🔥 изменений.

Я согласен с @felixfbecker
Все звучит потрясающе и улучшит качество как для разработчиков, так и для пользователей, но className изменится.

Возможность деконструировать все свойства, но одно, безусловно, вызовет больше путаницы и будет труднее объяснить новым пользователям, чем то, что им нужно использовать className, потому что class является ключевым словом (которое они могут ясно увидеть, когда допущена ошибка, так как оно окрашено по-другому) . Работа с классом при деконструкции требует введения нового синтаксиса или совершенно другого способа считывания этого конкретного свойства, которое будет работать только до тех пор, пока вам не понадобится использовать свойство rest.
Это создает много проблем только для того, чтобы спасти четырех персонажей.

@felixfbecker это может быть class / for в JSX и className / htmlFor в версии JS?

<label class="foo" for="bar">..</label>

было бы

React.createElement('label', {className: 'foo', htmlFor: 'bar'}, '..')

Отличный план! Приятно вот что! 👏👏👏

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

Значительно упростить систему событий (#4751).

Теперь реакция не может делегировать обработчик пользовательским элементам без расширения определения ReactDOM. https://github.com/facebook/реагировать/issues/9242

Это означает, что React не может установить собственный обработчик для пользовательского элемента, например <x-component onMyEvent={ev => {...}} />

@gaearon
У вас есть какие-нибудь планы на этот счет?

Все эти изменения превосходны, но, на мой взгляд, самое большое из них — это уменьшение размера. У React средний DX, но он достаточно толстый, чтобы его загрузка и парсинг в обычных сетях и, в частности, на мобильных устройствах, были проблемой.

У нас могло быть все!

Откроет ли переписывание делегирования события дверь для исправления #1254; где некоторые события снижают производительность узла, к которому они подключены (что для React означает все приложение).

Кроме того, в долгосрочной перспективе вы рассматривали возможность использования синтетических реквизитов dataSet? Невозможность вводить допустимые реквизиты HTML (из-за data-*) приводит к множеству ошибок при пересылке реквизитов узлам DOM. Текущие типизированные компоненты React должны выбирать между точными типами свойств и допустимыми атрибутами данных.

я взволнован

@ryanflorence Немного оффтоп, но немного грустно, что никому (насколько мне известно) не пришла в голову идея сделать трансформер html/css/svg -> jsx, чтобы облегчить миграцию в React с таким количеством тривиальных изменений в карте HTML. attrs для реквизита React. Столько человеко-часов потрачено впустую, в основном на поиск и замену :(

Очень странно видеть в том же номере (и комментариях) следующее:

Наша цель — сделать React более согласованным с тем, как работает DOM.
имя_класса → класс
Кажется странным все еще использовать clipPath, htmlFor, tabIndex и т. д.

Когда все это прямые аналоги DOM API

И этот аргумент не проходит проверку:

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

React всегда был очень тонким слоем поверх JS. Таким образом, все остальное, кроме угловых скобок JSX, было JS _и_ имело прямой аналог в DOM API для вещей, непосредственно связанных с DOM: className , clipPath , htmlFor , tabIndex и т. д. и т. д. и т. д.

С решением ввести class React перестает быть тонким слоем ( class — зарезервированное слово в JS) и отказывается от заявленной цели большей совместимости с DOM API.

Особенно неприятно видеть, что вы хотите «перейти от onChange к onInput», потому что это несовместимо с DOM _и_ становится несовместимым с DOM путем миграции className -> class .

Кроме того, это открывает полную банку червей, поскольку люди будут требовать (и уже требуют) изменений в других частях. Просто в комментариях: почему мы используем dataset вместо data-* ? Может быть, потому что data-* не является допустимым JS (очень похоже class ) и потому что он совместим с API DOM ? Почему бы нам не изменить htmlFor ? Потому что for — зарезервированное слово, а htmlFor — в DOM API? И т.д. и т.п.

И все же, если мы передадим неизвестную пару ключ/значение, она будет рассматриваться как атрибут, начиная с React 16. Так что мы уже несовместимы.

@gaearon , что также является причиной того, что React — единственная библиотека, получившая плохие оценки в тесте взаимодействия CustomElements Everywhere: https://custom-elements-everywhere.com/
И есть много вопросов, требующих его изменить: https://github.com/facebook/react/issues/11347 , https://github.com/facebook/react/issues/7249 , https://github.com/facebook .

Возможно, это не проблема, но не будет ли сходство React Fire с React Fiber сбивать с толку тех, для кого английский язык не является родным? Я часто думал, что Ньюаркский Пенсильванский вокзал и Нью-Йоркский Пенсильванский вокзал, находящиеся на одной линии поезда здесь, в Нью-Йорке, были особенно жестокой шуткой над туристами.

Если это действительно проблема, вы можете назвать это React Flame и при этом сохранить огонь 🔥 emoji.

Откроет ли переписывание делегирования события дверь для исправления #1254; где некоторые события снижают производительность узла, к которому они подключены (что для React означает все приложение).

Исправление # 1254 в той или иной форме, безусловно, то, что я хотел бы увидеть.

Кроме того, в долгосрочной перспективе вы рассматривали возможность использования синтетических реквизитов dataSet?

Я не хочу связываться с чем-то подобным сейчас, потому что есть большая поверхность. Более богатый интерфейс для DOM ( ariaSet , dataSet , classList ) имеет смысл, но неясно, сколько мы хотим инвестировать в это в React DOM по сравнению с библиотекой более высокого уровня, которая дает вам более богатый DOM API. Поскольку эти изменения носят более косметический характер, но имеют большую площадь поверхности, я бы воздержался от них.

Реагировать Пылающий 🔥

@ryanflorence Немного оффтоп, но немного грустно, что никому (насколько мне известно) не пришла в голову идея сделать трансформер html/css/svg -> jsx, чтобы облегчить миграцию в React с таким количеством тривиальных изменений в карте HTML. attrs для реквизита React. Столько человеко-часов потрачено впустую, в основном на поиск и замену :(

@jxub
https://transform.now.sh/html-to-jsx/

Так рады новым изменениям, что вы, люди из Facebook, творите историю с этой миграцией. 50 000 компонентов будут перенесены в React Fire?
Ваши тестовые наборы должны быть такими плотными <3

не будет ли сходство React Fire и React Fiber сбивать с толку тех, для кого английский язык не является родным?

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

Спасибо, что поделились @gaearon , это потрясающе!

Я бы хотел увидеть выпуск JSX 2.0, решающий проблему пробелов и новых строк, которая возникает, когда мы компилируем наш код с помощью Babel и Typescript.

Были открыты разные проблемы, и я пытался внести свой вклад, но мне отказали, потому что команде React нужно проверить все, что связано с JSX.

Эта проблема в любом случае относится к dom, потому что способ, которым мы переводим jsx в js, не позволяет тому, что говорит w3c.

Это проблема https://github.com/facebook/jsx/issues/19

Мой комментарий в самом конце.

Я думаю, className в порядке. Пусть будет то, что есть. Не добавляйте оскорбление к травме.

Может кто-нибудь пояснить, как это влияет на существующие обработчики?

Прекратить отражать входные значения в атрибуте value

Будет ли React по-прежнему иметь контролируемые входные данные с точными обновлениями event.target.value в обработчиках, или это повлияет только на чтение значений из ссылок и узлов DOM?

@nickmccurdy влияет на то, что вы видите в инструментах разработки браузера.

@tomdale React Ember 🔥

Хороший! Я жду, чтобы увидеть полный список изменений в React 17.
Я верю, что это будет новая эра ReactJS. 🔥⚛️

@tomdale Хм: пряжа, волокно, ткань; может быть, можно использовать другой термин, связанный с одеждой? 😆

И все же, если мы передадим неизвестную пару ключ/значение, она будет рассматриваться как атрибут, начиная с React 16. Так что мы уже несовместимы.

@gaearon , что также является причиной того, что React — единственная библиотека, получившая плохие оценки в тесте взаимодействия CustomElements Everywhere: https://custom-elements-everywhere.com/

Нет, причина не в этом (пользовательские и обычные элементы — это совершенно разные пути кода). Причина в том, что у нас уже было старое поведение, и мы не хотели нарушать обратную совместимость, если новое поведение не было надежным. Я думаю, что было бы целесообразно улучшить взаимодействие с пользовательскими элементами как часть этого зонтика.

не будет ли сходство React Fire и React Fiber сбивать с толку тех, для кого английский язык не является родным?

Оба являются внутренними кодовыми именами и не имеют никакого значения после завершения проектов. React Fire — это всего лишь попытка сделать React DOM лучше, и к тому времени, когда он будет готов к производству, это будет просто React DOM.

Будет ли React по-прежнему иметь контролируемые входные данные с точными обновлениями event.target.value в обработчиках, или это влияет только на чтение значений из ссылок и узлов DOM?

Да, потому что event.target.value — это свойство . Мы говорим о прекращении обновления атрибутов . Чего не делают никакие другие популярные библиотеки (насколько мне известно) и что вызывает бесчисленное количество проблем. Это не должно влиять на ваш код, если вы не полагаетесь на селекторы CSS для значения (что, вероятно, в любом случае плохо ).

Хороший! Я жду, чтобы увидеть полный список изменений в React 17.

Обратите внимание, что мы не обещаем, что это будет готово к 17. Это может быть 18. Или 19. 😅

Приятно видеть стабильное развитие такой хорошей библиотеки, как React. 🎉 class значительно улучшит удобство использования, оно того стоит.

@gaearon

пользовательские и обычные элементы — это совершенно разные пути кода

Это тоже похоже на то, что нужно исправить. Есть ли причина не относиться ко всем элементам одинаково? Это цель спецификаций HTML и DOM.

@justinfagnani Как обсуждалось ранее, причина, по которой мы не сделали этого в то время, заключалась в том, что не было соглашения о том, как определить, установить ли свойство или атрибут, и существовал риск того, что, используя проверку, мы рискуем сделать это веб-платформа не может добавлять новые свойства в прототип. Я думаю, что к настоящему моменту в RFC и PR, над которыми работал @robdodson , уже есть какой-то консенсус, и мы, вероятно, сможем его оттуда извлечь.

👍 🔥 🔥 🔥

React Fire также должен позволить нам применить некоторые умные оптимизации производительности, которые есть у Inferno, но которые мы не смогли применить из-за критических изменений. Волнительные времена :)

ЛГТМ

В связи с предложенным переименованием className -> class : мне бы хотелось, чтобы свойство classes принимало массив строк. Это избавило бы меня от множества манипуляций со строками (или использования имен классов ) в моих компонентах.

Я думаю, что единственным недостатком реквизита classes будет то, что массивы, содержащие одни и те же строки в одном и том же порядке, вызовут повторный рендеринг в чистом компоненте, а строка тех же классов CSS - нет. Хотя, если честно, это кажется незначительной проблемой. Я думаю, что большинство разработчиков React уже знают о компромиссах между массивами и объектами в свойствах.

У @gaearon есть планы по обратной совместимости? Может быть, пойти по тому же пути, что и React Fiber, добавляя предупреждения об изменениях и давая время для обновления больших кодовых баз без потери новых обновлений.

Что касается class и className .

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

Компонентный API должен казаться идиоматичным

Существует распространенный аргумент, что React «соответствует JavaScript», поэтому предпочтительнее className . Я думаю, что это утверждение слегка неправильно понято, поэтому я хотел бы немного сосредоточиться на нем.

В React, в первую очередь, мы заботимся о том, чтобы использование компонента React было похоже на идиоматический JavaScript . Это означает, что если я использую гипотетический компонент <Table> , я ожидаю, что его реквизиты будут в стиле camelCase:

<Table
  rowHeight={10}
  headerBorderInset={5}
  renderRow={this.renderRow}
/>

Я не ожидаю увидеть такие имена свойств, как row_height или row-height в общедоступном API компонента . Реквизиты компонента — это объект (что-то вроде «пакета опций»), и мы обычно ожидаем, что эти опции будут camelCase . Возможно, это не всегда идиоматично в DOM, но во многих местах DOM не очень последовательна. React согласуется с экосистемой JavaScript, которая в подавляющем большинстве использует camelCase .

А как же ДОМ? Вот где это становится тернистым.

Свойства DOM — это не просто «атрибуты в JS»

В DOM у нас есть атрибуты и свойства. Атрибуты — это то, что вы обычно видите в HTML. Свойства — это то, что вы обычно устанавливаете в JS. Но что особенно важно, DOM API существуют как для установки свойств, так и для установки атрибутов — и они даже не всегда устанавливают одно и то же.

node.value = 10; // setting a property
node.setAttribute('value', '10'); // setting an attribute

Во многих случаях это не имеет значения. В некоторых случаях это так. Но, возможно, не так, как можно было бы подумать, используя React (который имеет одну абстракцию над обоими).

React — это не просто установка свойств

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

На самом деле React в настоящее время использует атрибуты почти для всех поддерживаемых им реквизитов. В некоторых случаях, например value , это вызывает проблемы (которые, как я уже говорил, мы хотим исправить). В других случаях это действительно здорово — потому что нам не нужно включать список поддерживаемых свойств в комплект React. Использование атрибутов под капотом — это то, что позволило значительно уменьшить размер в React 16.

Я хочу сказать, что то, использует ли React свойства или атрибуты внутри, является деталью реализации и не имеет ничего общего с тем, должен ли элемент React DOM _API_ использовать имена свойств, имена атрибутов или даже некоторые другие имена, которые имеют смысл.

Тем не менее, давайте просто использовать имена свойств?

Ладно, свойства и атрибуты — это деталь реализации. Но почему бы просто не стандартизировать использование имен свойств DOM, поскольку они были специально созданы «для JavaScript»? Разве не так устроен сегодня React API?

Ну, не совсем. Только одно из перечисленных ниже свойств соответствует реальному свойству объекта DOM:

<div
  tabIndex={1}
  data-id="123"
  aria-live="polite"
  nopin="nopin"
  itemType="http://schema.org/Movie"
  onClick={function() { alert('hi') }}
/>

По иронии судьбы, единственное указанное выше свойство, имеющее фактическое свойство DOM с тем же именем, которое ему соответствует ( tabIndex , если вы не уверены), на самом деле устанавливается React в качестве атрибута!

Так что к этому моменту вы, вероятно, заметите, что это не является ни четким, ни последовательным. В некоторых случаях свойства не существуют (например, для пользовательских, нестандартных атрибутов), в некоторых случаях React может предоставить более богатый API ( data- против dataSet ), но в настоящее время его нет.

В некоторых случаях React намеренно выбирает отклонение ( onClick в свойстве React против onclick DOM), потому что это имеет больше смысла для пользовательских компонентов React. Это связано с тем, что компоненты React часто предоставляют более сложные обработчики событий, такие как onItemClick . Было бы очень непоследовательно, если бы вы написали <Button onclick> вместо <Table onItemClick> . И <Table onitemclick> не является camelCase, которого мы хотели избежать в компонентном API.

Выше я объяснил, что React уже не соответствует принципу «всегда использовать имя свойства DOM», что React даже фактически не использует свойства внутри (так что эмпирическое правило также не описывает реальную механику), и что во многих случаях случаях свойств DOM просто не существует, поэтому мы должны придерживаться разрешения имени атрибута.

Если не имена свойств, давайте будем последовательны и будем использовать имена атрибутов?

Так почему бы не использовать только имена атрибутов? Это может быть правдоподобно. Но теперь мы натыкаемся на самое первое соображение, которое мы выдвинули. Использование компонента React должно быть похоже на идиоматический JavaScript . Но часто компоненты передают по крайней мере некоторые реквизиты базовому элементу DOM.

<Button
  borderColor='red'
  tabIndex={1}
 />

 // renders...

 <button
   tabIndex={1}
/>

Для пользовательского Button было бы неудобно принимать реквизиты с непоследовательным регистром заглавных букв:

<Button
  borderColor='red'
  tabindex={1}
 />

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

Я думаю, что это основная причина, по которой желательно, чтобы реквизиты, такие как tabIndex , cellSpacing и большинство других реквизитов, связанных с DOM, следовали соглашению camelCase. Это потому, что они часто оказываются в компонентных API.

Мы хотим упростить для пользовательских компонентов, таких как Button , перенос и пересылку их без «преобразования» их в имя атрибута в точке, где они перетекают в DOM, и без добавления реквизитов, отличных от CamelCase, в API пользовательского компонента.

Это также объясняет, почему реквизиты, такие как data-* , aria-* и пользовательские атрибуты, являются разумными исключениями (хотя мы могли бы сделать для них более богатые API). Они редко передаются пользовательским компонентам. Как правило, они слишком связаны с DOM, чтобы быть полезными в пользовательских компонентах, и вместо этого становятся деталями реализации чего-то вроде <Modal> или <Button> с более богатым API camelCase.

Свойства React уже не соответствуют свойствам DOM

Если соглашение «имя свойства DOM» не сработало, нам нужно что-то еще. Что это такое? Может ли это быть «верблюжья версия имени атрибута»? Кажется, что это почти всегда уже подтверждается.

Если это звучит слишком радикально, считайте, что мы уже делаем это. Мы поддерживаем то, что называется srcSet . Но имя свойства DOM для него srcset . У нас есть autoCapitalize , но свойство DOM называется autocapitalize . У нас есть autoFocus , но свойство DOM равно autofocus .

Мы уже отклоняемся от имен свойств DOM, когда они не соответствуют соглашению JavaScript camelCase. Что приводит нас к class .

Наконец: className против class

Частично первоначальное обоснование для того, чтобы сделать его className , заключалось в том, что React устанавливал свойства DOM, а className — это имя свойства DOM.

Однако, как я объяснил выше, React больше не использует свойства, кроме трех или четырех особых случаев. Что еще более важно, React даже не последовательно использует имена свойств DOM — скорее, он использует имена, которые выглядели бы естественными при использовании из JavaScript, независимо от внутреннего несоответствия именования как в атрибутах DOM, так и в именах свойств. И это потому, что React больше всего заботится о том, чтобы имена свойств для пользовательских компонентов выглядели как «JavaScripty». В этом смысле tabindex не является «JavaScripty», но и class , и className являются таковыми.

Еще одним аргументом против class на раннем этапе было то, что такой код не был допустимым для ES3 (актуально для IE8):

// Not valid in ES3
// Valid in ES5
var props = { class: 'foo' };

Но большинство больше не пишет ES3. Либо вы используете цепочку инструментов вроде Babel, либо, скорее всего, ориентируетесь на IE9+ — React сейчас даже не поддерживает IE8.

Таким образом, единственное неудобство, оставшееся с class , заключается в том, что вы не можете написать это:

// Not valid at all :-(
const class = props.class;
const { class } = props;

Но я думаю, что со временем этот аргумент сам по себе недостаточно силен. React не заставляет вас использовать деструктурирование или использовать это конкретное имя переменной и писать что-то вроде

// Valid
const {class: cls} = foo;
const cls = props.class;

не так уж больше усилий.

Обычно люди пропускают class гораздо чаще, чем читают его, потому что многие компоненты содержат более одного внутреннего <div> или других основных элементов. Таким образом, вы в конечном итоге пишете <div className> гораздо чаще, чем хотите деструктурировать class . Таким образом, изменение на class сэкономит больше времени на клавиатуре, чем принесет.

Здесь есть еще один важный момент.

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

Если вы пишете компонент, который очень близок к DOM (и, следовательно, имеет смысл использовать class в качестве реквизита), вы, вероятно, захотите перенаправить и другие реквизиты. Таким образом, вы можете использовать синтаксис rest при деструктурировании:

// Valid in ES2018

function Button({ color, ...rest }) {
  const buttonClass = rest.class +  ' Button-' + color;
  return <button {...rest} class={buttonClass} />
}

И если бы вам не нужно было его модифицировать, вы могли бы просто переслать {...rest} , даже не читая из него class . Таким образом, ограничение деструктурирования может способствовать лучшему проектированию компонентов.

Почему не оба?

why not both

Наконец, не можем ли мы просто поддерживать как class , так и className ? В каком-то смысле мы уже это делаем, но React кричит вам за это предупреждением. Для этого есть причина.

Если мы поддержим оба без предупреждений, то сообщество разделится по поводу того, какой из них использовать. Каждый компонент в npm, который принимает свойство класса, должен помнить о пересылке обоих. Если хотя бы один компонент посередине не подыгрывает и реализует только один реквизит, класс теряется — или вы рискуете получить class и className внизу, «несогласные» с каждым другой, и у React нет возможности разрешить этот конфликт. Поэтому мы думаем, что это будет хуже, чем статус-кво, и хотим этого избежать.

Резюме

Если бы сегодня React был открытым исходным кодом, казалось бы, плюсы разрешения class (концептуально ближе к тому, что ожидает большинство людей, меньше печатать для наиболее часто используемого реквизита) перевешивают недостатки (чуть больше печатать, чтобы перехватить его — в в каких случаях вам, вероятно, все равно понадобится оператор спреда).

То, что мы привыкли считать недостатками (несовместимость со свойствами DOM), является спорным, потому что мы больше не устанавливаем свойства DOM и даже не стремимся соответствовать им. Вместо этого мы стремимся иметь основанный на атрибутах, но camelCase API на потребляющей стороне компонентов React, в чем мы уже почти последовательны. И class="Button" явно удобнее, чем className="Button" . На самом деле, если бы DOM API был разработан сегодня, он, вероятно, позволил бы вам установить свойство .class именно потому, что ограничение на использование class в таком назначении было снято в ES5 — почти десять лет назад.

Единственным оставшимся большим недостатком является стоимость миграции. Мы тщательно это оценим. Но если мы все равно вносим кучу изменений, возможно, мы сможем внести и это и исправить его навсегда. Мы не думаем об этом легкомысленно и учитываем все ваши опасения.

Примечание. Это может иметь смысл для других имен свойств React, которые не соответствуют именам атрибутов в стиле camelCased.

@renatoagds

есть планы по обратной совместимости? Может быть, пойти по тому же пути, что и React Fiber, добавляя предупреждения об изменениях и давая время для больших обновлений кодовых баз.

Как я заметил:

И у нас есть более 50 тысяч компонентов в Facebook, чтобы мы оставались честными в отношении нашей стратегии миграции. Мы не можем позволить себе переписывать код продукта, за исключением нескольких целевых исправлений или автоматических модификаций кода.

Так что мы обязательно постараемся сделать стратегию миграции как можно более плавной, как всегда. Если это не гладко, мы не сможем внести изменения самостоятельно.

re: className -> class, я согласен с любым решением, я определенно вижу исключение для изменения класса для новых пользователей и дополнительное преимущество более коротких строк кода. Хотя им все равно нужно будет узнать о других именах camelCase.

Таким образом, единственное неудобство, оставшееся с классом, заключается в том, что вы не можете написать это:

const { class } = props;

Но я думаю, что со временем этот аргумент сам по себе недостаточно силен. React не заставляет вас использовать > деструктурирование и написание

const class = props.class;

не так уж больше усилий.

Две (возможно, небольшие) вещи:

  1. Разве const class = props.class не является недопустимым JavaScript? Я не думал, что это так, и в быстром тесте Chrome это не нравится. Кроме того, эта статья предполагает, что это недействительно.

  2. Я мог видеть, что это изменение является (опять же, потенциально небольшим) областью разочарования для людей, которые пишут такие компоненты, как этот: nvm (см. Обновление ниже)

const { oneProp, twoProp, className, ...rest }  = this.props;

// do stuff with oneProp, twoProp, className

return (
  <div
    someProp={prop}
    anotherProp={anotherProp}
    className={someClassName}
    {...rest}/>
);

После этого изменения это должно быть что-то вроде...

const { oneProp, twoProp, ...rest }  = this.props;

// do stuff with oneProp, twoProp, this.props.className

return (
  <div
    someProp={prop}
    anotherProp={anotherProp}
    {...rest}
    class={someClassName}/>
);

Обойти это изменение можно, но нужно помнить об этом при написании и чтении компонентов в этом стиле.

Обновление :

Неважно,

const { class: className } = this.props;

делает свое дело.

Единственным оставшимся большим недостатком является стоимость миграции. Мы тщательно это оценим. Но если мы все равно вносим кучу изменений, возможно, мы сможем внести и это и исправить его навсегда. Мы не думаем об этом легкомысленно и учитываем все ваши опасения.

К счастью, это легко исправить, если использовать подход CSS-in-JS, например Aesthetic. Спасибо за удивительную запись!

Случайный совет относительно имен атрибутов, я нашел отличный проект, svg2jsx отлично подходит для преобразования больших SVG для использования в React!

@jamesplease Извините, мой разум пуст — вы правы. Отредактировано.

@jamesplease ты прав. Это также часто возникает при работе с JSON для значения по умолчанию, что так раздражает!

const { default: defaultVal } = property

Пока вы меняете систему событий, было бы неплохо увидеть что-то похожее на функцию linkEvent в Inferno, чтобы мы могли выполнять обработку событий, используя реквизиты в функциональных компонентах, без необходимости создавать анонимную функцию при каждом рендеринге.

className -> class станет огромным изменением для экосистемы, многие неподдерживаемые компоненты станут несовместимыми, и вы ничего не сможете сделать, если не сможете их исправить. Может быть, есть какая-то оболочка, такая как StrictMode , которая отключает это изменение для компонентов, находящихся глубже в дереве, чтобы обеспечить постепенный путь миграции?

Я мог видеть, что это изменение является (опять же, потенциально небольшим) местом разочарования для людей, которые пишут такие компоненты:

const { oneProp, twoProp, className, ...rest }  = this.props;

// do stuff with oneProp, twoProp, className

return (
 <div className={someClassName} {...rest}/>
);

Только не разрушай его.

const { oneProp, twoProp, ...rest }  = this.props;

return (
  <div
    {...rest}
    class={'something ' + rest.class}
  />
);

@gaearon

использует ли React свойства или атрибуты внутри, является деталью реализации

Это тоже похоже на проблему, если честно. Элементы DOM могут и ведут себя по-разному в некоторых случаях в зависимости от того, устанавливаете ли вы атрибуты или свойства. React не может знать обо всех различиях, но пользователи элементов могут знать об элементах, которые они используют. Явный контроль над свойствами, атрибутами и событиями позволил бы авторам выйти из этой ситуации.

@justinfagnani Если у вас есть определенные вещи, которые вы хотели бы, чтобы мы изменили, не могли бы вы подать отдельную заявку с API, который вы предлагаете? Это звучит немного не в рамках данного вопроса.

@сомпиласар

className -> class будет огромным изменением для экосистемы, многие неподдерживаемые компоненты станут несовместимыми, и вы ничего не сможете сделать, если не сможете их исправить. Может быть, есть какая-то оболочка, такая как StrictMode, которая отключает это изменение для компонентов, находящихся глубже в дереве, чтобы обеспечить постепенный путь миграции?

Я согласен — и мы все еще взвешиваем за и против. Ничего не доработано.

Но на практике проблема неподдерживаемых компонентов не нова — она возникает в каждом мажорном релизе React, потому что что-то меняется в мажорах по определению (иначе мы не можем двигаться дальше, и у нас нет роскоши хранить весь устаревший код в пакет навсегда, в отличие, например, от серверных сред). Та же проблема возникла, когда PropTypes был перемещен в отдельный пакет, и повторится с переименованием жизненного цикла UNSAFE_ . Неподдерживаемые пакеты разветвляются или исправляются. Мы понимаем, что это большая трата времени, и именно поэтому мы избегаем делать более одного крупного проекта в год. Для людей, которые не могут позволить себе помочь, обычно лучше подождать несколько месяцев, прежде чем переходить на новую специальность, потому что ранние последователи прокладывают путь и оживляют заброшенные пакеты. Тогда мы идем вперед все вместе.

Опять же — я очень понимаю ваше колебание, но это принципиально не отличается от других кардинальных изменений, которые произошли в прошлом или могут произойти в будущем. Как всегда, мы приложим много усилий и акцентируем внимание на автоматических сценариях, которые вы можете запускать для преобразования большей части вашей кодовой базы, а также на других пакетах (и отправлять им PR — или разветвлять их в их последнем состоянии). ).

Независимо от вашего решения, еще один аргумент против class — возможность поиска. Сколько ложных срабатываний даст вам поиск по class , когда вы хотите найти компоненты, использующие классы CSS, в коде ES6, который использует компоненты класса JS? Да, вы можете искать class={ , но как насчет деструктуризации реквизита в JSX, созданного как объект в JS? (Я против интенсивного использования деструктуризации пропсов, но они все еще используются) Конечно, нам нужны более эффективные контекстно-зависимые инструменты поиска на основе AST в редакторах кода, но пока у нас есть только текст и регулярное выражение. Конечно, системы типов могут помочь отслеживать прохождение объектов, но большая часть населения их не приняла.

Что-то в использовании зарезервированного слова меня не устраивает, даже если сейчас это не вызывает никаких проблем; можем ли мы с уверенностью сказать, что rest.class (например) не будет иметь значения для языка через x лет?

@GeordieP Если это работает сегодня, то завтра не сломается. Это основной принцип развития JavaScript и причина многих его особенностей.

@gaearon Тогда достаточно честно. Если это достаточно большая победа, я говорю, дерзайте.

@sompylasar Я обычно ищу className= или className: , похоже, оба они будут работать и с class .

Пожалуйста, избавьтесь от className и, ради бога, от htmlFor . Я не разработчик DOM, обычно что-то очень не так, если мне нужно получить доступ к собственным методам DOM. Самая большая проблема, с которой я столкнулся при адаптации людей к React, — это абстракция, которую JSX делает поверх DOM, и его странные заменяющие HTML-атрибуты. Все транспилируется, на данный момент нет причин беспокоиться о зарезервированных словах. ИМО.

Не уверен, что это что-то добавляет к существующему обсуждению, но кажется, что должна быть веская причина для изменения className .

Стоит ли спасать новичков, изучающих React, от немного неинтуитивного имени, чтобы всем пришлось обновлять свои проекты и поведение?

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

Кроме того, не будут ли новички все еще сбиты с толку огромным количеством материалов (таких как блоги/репозитории/и т. д.), которые в настоящее время используют className ?

Наконец, как сказал @sompylasar , это ухудшает возможности поиска в моей кодовой базе.

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

Немного оффтоп, но это немного грустно, что никому (насколько я знаю) не пришла в голову идея сделать трансформер html/css/svg -> jsx, чтобы упростить миграцию в React с таким количеством тривиальных изменений для сопоставления атрибутов HTML с Реагируйте на реквизиты.

@jxub — я создал конвертер HTML в JSX в рамках хакатона еще в 2014 году: https://magic.reactjs.net/htmltojsx.htm. Однако я не уверен, что он хорошо обрабатывает SVG. Проект хакатона заключался в том, чтобы создать скрипт, который бы «ajaxify» простой HTML-сайт с помощью React (https://github.com/reactjs/react-magic), и часть этого потребовала от меня создания способа создания компонента React. из фрагмента HTML, поэтому я выпустил часть HTML для JSX как отдельную отдельную страницу.

Мы по-прежнему заботимся о поддержке IE11, но, возможно, мы не будем пытаться сгладить некоторые из существующих различий между браузерами — такова позиция многих современных UI-библиотек.

@gaearon - Какие есть примеры современных библиотек пользовательского интерфейса, которые не сглаживают различия в браузерах? Для меня это одна из основных причин использования библиотеки.

Теория заговора: вся эта новость className/class — одна яркая спорная вещь, на которую все сразу обратят внимание и о которой поспорят. Либо привлечь внимание к реворку в целом, либо отвлечь от чего-то большего, что происходит в тени, либо дать что-то одно, от чего потом можно отказаться, а остальное примут, как в следующем анекдоте:

Великий театральный художник Тышлер, создавая эскизы декораций, в углу рисует маленькую зеленую собачку. И когда одна из приемных комиссий спросила: «Мне все нравится, а где эта собака?», артистка со вздохом сожаления залепила ее.

Истинные причины этого изменения неясны, но они уже привели к резкому росту популярности этого нового проекта обновления и шумихи вокруг React в сообществе.

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

6436

Спасибо за всю вашу тяжелую работу над этим, но, пожалуйста, пересмотрите className -> class .

Все мы когда-то были новичками в React, и className не помешали нам изучить и полюбить React.

Я помню, когда я использую vue с jsx, у них уже было class не className , я не согласен, если className будет изменен на class , потому что React является пионером в Virtual DOM , и представлять сам DOM.

Прикрепляйте события к корню React, а не к документу

@gaearon Означает ли это, что в среде тестирования мне не нужно будет добавлять элементы в документ, чтобы иметь возможность отправлять реальные события браузера и вызывать связанные с ними обработчики? Необходимость делать это очень нелогична, и я уверен, что многие разработчики, незнакомые с внутренностями React, запутались, тратят много времени на написание тестов и участвуют в моделировании событий и плохих методах тестирования.

Это подводит меня к другой заметке: можем ли мы что-нибудь сделать с react-dom/test-utils ? Я особенно заинтересован в возможном удалении Simulate , учитывая все связанные с ним проблемы, которые мы все знаем, и, конечно же, внести необходимые изменения в сам react-dom , чтобы он действительно не был нужен. больше. Может ли это быть в рамках?

/cc @kentcdodds

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

Люблю большинство объявленных изменений, но я скептически отношусь к изменению className .

React не заставляет вас использовать деструктурирование или использовать это конкретное имя переменной, и написание чего-то вроде (...фрагмент кода...) не требует больших усилий.

Хотя писать не так уж и сложно, по моему нынешнему опыту я ожидаю, что это будет _намного_ сложнее объяснить другим разработчикам (особенно разработчикам других языков). С другой стороны, за все годы, что мы использовали React в нашей компании, я думаю, только один или два разработчика были сбиты с толку className и просто приняли это как API Reacts для установки имен классов за пару минут.

(По моему личному мнению, хотя я _люблю_ деструктировать, синтаксис переименования иногда сам по себе кажется странным для новичков, потому что он отличается от переименования в импорте, который выглядит очень похоже и может комбинироваться с такими вещами, как значения по умолчанию. Можно было бы просто не использовать деструктирование, тогда , но это было бы _большим_ исключением из всего остального кода, который мы сейчас пишем в нашей компании. Опыт других может, конечно, отличаться, но это мой взгляд на проблему 🙃.)

отличный

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

Стоит ли тратить столько политического капитала на изменение, когда объявляется так много других хороших вещей?

С моей точки зрения, если вы принимаете решение, часть обоснования которого состоит в том, что «и написать что-то вроде... ... не требует больших усилий», это решение должно иметь _огромный_ положительный эффект, и изменение className -> class просто не идет ни в какое сравнение со всем остальным, о чем было объявлено.

это будет большим шагом вперед в 🔥 React Fire

Что касается class против className , я думаю, мы должны напомнить себе, что JSX ≠ React.

Поскольку JSX — это _DSL_, который выглядит как HTML, лучше всего, чтобы он был как можно ближе к HTML. Конечно, в DOM API он называется className , но большинство из них используют JSX, вероятно, потому, что не хотят напрямую работать с DOM API.

Если для React API имеет больше смысла точно соответствовать DOM API, то я надеюсь, что это нормально/возможно выполнить сопоставление в транспиляции:
<img src="avatar.png" class="profile" />React.createElement("img", { src: "avatar.png", className: "profile" }) .

Было бы очень полезно сделать синтаксис JSX чистым надмножеством HTML.

Чтобы добавить к тому, что сказал @ mhenr18 .

Текущее положение вещей:

  • Реагировать непоследовательно
  • API в верблюжьем регистре

Предлагаемое положение вещей:

  • Реагировать непоследовательно
  • API в верблюжьем регистре
  • className -> class

Воспринимаемые преимущества:

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

Собственно минусы:

  • вся экосистема, которая зависит от className , перестает работать (огромные усилия по обновлению)
  • весь огромный массив книг, руководств, примеров, кода, постов, статей становится слегка недействительным
  • единственный оставшийся действительный JS - это дополнительный ввод : const {class: cls} = props . Любой другой возможный вариант использования в простом JS становится недействительным.
  • React API остается непоследовательным и нарушает дальнейшие предположения (почему htmlFor , а не for и т. д.)

Если бы я был продакт-менеджером, моя непосредственная реакция на изменение была бы такой: что?

@gaearon Возможно, вы уже обдумывали это, отметьте PR с помощью «React Fire» или аналогичного ключевого слова.

Проблемы обычно помечаются правильно, иногда их нет у PR. Это помогает потенциальным участникам.
Это исходит из моего опыта, когда я пытался прочитать историю git в поисках коммитов, связанных с React Fiber и React Reconciler, на протяжении всей разработки Fiber. Это помогает тем из нас, кто пытается выяснить, что происходит, и увидеть, можем ли мы каким-то образом внести свой вклад.

Я также думаю, что переименование className в class вызовет такие большие усилия по миграции и проблемы для новых разработчиков.
Атрибут className настолько заметен и часто используется, что он буквально сломает все библиотеки, полагающиеся на реакцию.
И этого недостаточно, большинство туториалов будут сломаны. Новое устройство, копирующее и вставляющее из статьи, будет задаваться вопросом: «Почему это не работает, там написано, что className не является допустимой опорой».
Таким образом, старший должен помочь, и мы ничего не выиграли, потому что нам все еще нужно объяснить, почему это не работает, как вы ожидаете.
И на самом деле, объяснение того, что вы должны использовать className для определения классов в компоненте, занимает меньше минуты и легко понятно. Объяснение каждому разработчику, почему они изменились с className на class , занимает гораздо больше времени и приводит к еще большему разочарованию.

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

Пожалуйста, подумайте, стоит ли оно того?

Я использую babel-plugin-react-html-attrs в течение многих лет, и он хорошо мне служит, я не думаю, что переименование className в class — хорошая идея. Это лучше достигается с помощью плагина, подобного тому, который я упомянул.

Разве не было плагина Babel для обработки всей ситуации « class v className » / « for v htmlFor »?

Я надеюсь, что возможно поддерживать атрибуты html как есть, сохраняя при этом обратную совместимость с уже принятыми решениями об именах.

Тот факт, что уже есть плагины babel для преобразования, возможно, свидетельствует о том, что должна быть возможность поддерживать его в самом основном транспиляторе JSX. Но если бы это была официальная спецификация, все стало бы намного проще и надежнее для всех.

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

Пересмотрите className по сравнению с class . Как было сказано выше, выигрыша практически нет, но есть и реальные недостатки.

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

class — это зарезервированное ключевое слово в большинстве языков программирования, и мы просто не могли больше манипулировать этим реквизитом, что делало приложение React почти невозможным (удачи в создании настоящего без манипулирования классами). То же самое касается htmlFor vs for , к сожалению (это действительно уродливо, но я благодарен, что он существует).

Да, кстати, возможность поиска... Представьте, что вы гуглите «класс React», вы получите смешанные сигналы: компоненты класса React, атрибут класса React. Вы гуглите «React className», вы получите устаревшую документацию (люди упомянули выше, что огромное количество работы по обновлению связано с этим изменением, помимо обновлений кода).

Является ли целью этого проекта больше работы для сообщества и больше шума и смешанных сигналов для Интернета? Надеюсь нет.

Да, экосистема Интернета и JavaScript изо всех сил пытается поддерживать обратную совместимость из-за глупых ошибок прошлого, но это стремление к обратной совместимости позволило ей вырасти до такого масштаба без серьезной фрагментации.

Я понимаю, что без изменений нет прогресса, и я принял девиз раннего FB: ломать вещи, чтобы двигаться быстро (также имея план, как собрать их обратно заранее).

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

@sompylasar Обычно я ищу className= или className:, похоже, оба они будут работать и с классом.

Кроме того, удачи в этом прямо на github =/

Я прочитал все комментарии здесь. Я согласен с изменениями, но не уверен насчет class . Основная причина в том, что он не будет работать с планами для JSX 2.0. о сокращенной нотации (как у нас сейчас в объектах).
Все остальное кажется очень приятными улучшениями.
Ждем окончательного решения :) Спасибо за ваши удивительные усилия, ребята!

В одном из своих комментариев вы упомянули «если это работает сегодня, то должно работать и завтра». Имейте это в виду, прежде чем мой вопрос ;).

Я поддерживаю библиотеку пользовательского интерфейса под названием RMWC https://jamesmfriedman.github.io/rmwc/ , которая нацелена на все версии React до 15.4. Мне удалось сохранить унифицированную поверхность API, но изменение className на class, onChange на onInput и перестройка системы событий сделают это практически невозможным.

Есть ли какая-нибудь возможность «совместимого» уровня, который мог бы переводить некоторые из этих вещей под капот? Так что я могу писать в любой версии React Fire, но продолжать работать в более низкой среде выполнения.

Если нет, я ожидаю, что мой странный код станет еще более странным. 👀

если className действительно нужно изменить на class , пожалуйста, также измените htmlFor на for .
поскольку class и for изначально недействительны, когда мы деструктурируем props .

Если у React есть собственный API, который нормализует множество имен атрибутов для создания согласованного API, то, безусловно, className идеально подходит для этого. Одно дополнительное идиоматическое обучение в дополнение к идиомам camelCase, а также тот факт, что оно отображается на имя свойства DOM (как и некоторые другие атрибуты JSX), безусловно, хорошо по сравнению с необходимостью деструктурировать его как особый случай каждый раз, когда вы используете объект реквизита с ним.

Я чувствую, что до сих пор вы слышали много громких мнений против статус-кво («почему у нас не может быть класса?!»), В то время как все, кто был доволен его использованием, молчали; в соответствии со старой поговоркой, что люди гораздо чаще оставляют отрицательные отзывы, чем положительные. Лично я думаю, что крошечная кривая обучения поверх многих других намного лучше, чем специальное покрытие этого реквизита каждый раз, когда он появляется.

Я думаю, что хотел бы, чтобы вокруг этого было немного больше демократии — я думаю, что это очень конкретное изменение может быть сделано комитетом (по сути, это был псевдокомитет, который заставил вас рассмотреть это изменение) — и я счастлив быть на проигравшая сторона. Просто так, чтобы это затрагивало наименьших людей изо дня в день.

Ps все остальное выглядит отлично, особенно ивент 👌🏻

ждем новых обновлений

@gaearon Стоит ли учитывать, что ваш собственный пример:

const { oneProp, twoProp, ...rest }  = this.props;

return (
  <div class={'something ' + rest.class} {...rest}/>
);

содержит ошибку и не будет работать так, как вы ожидаете? Это может быть не так просто, как «Только не разрушай его».

я единственный, кто не был обеспокоен тем, что класс является className? Если бы вы спросили меня, какие проблемы были у React, я бы даже не подумал.

Тем не менее, обновления бесплатные, а я люблю бесплатные.

я единственный, кто не был обеспокоен тем, что класс является className?

Я совсем не беспокоюсь о классе. Незначительные ошибки с IE11 будут смешнее (и тем не менее я все еще более чем доволен этими изменениями)

Было бы неплохо, если бы поддержка пассивных прослушивателей событий была в рамках React Fire, что является важной функцией для мобильных устройств. №6436

Я согласен. Это определенно входит в рамки этой работы.

Привет @gaearon - прежде всего спасибо.

Рассматривали ли вы проведение опроса, чтобы собрать информацию о том, как люди используют реакцию, какие API используются и что сбивает с толку?

Хотя React, безусловно, является моим любимым стеком разработки интерфейса, я обнаружил, что при его изучении и первом использовании есть несколько подводных камней. Я не хочу просто излагать то, что люди, которых я учил, лично сбивали с толку.

Я обнаружил, что это полезно в проектах, в которых я лично участвовал (Node, Bluebird и т. д.).


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

Рассматривали ли вы проведение опроса, чтобы собрать информацию о том, как люди используют реакцию >, какие API используются и что сбивает с толку?

Я думаю, что у react-native есть canny.io. Я не знал, что у react нет

Я поддерживаю библиотеку пользовательского интерфейса под названием RMWC https://jamesmfriedman.github.io/rmwc/ , которая нацелена на все версии React до 15.4. Мне удалось сохранить унифицированную поверхность API, но изменение className на class, onChange на onInput и перестройка системы событий сделают это практически невозможным.

Есть ли какая-нибудь возможность «совместимого» уровня, который мог бы переводить некоторые из этих вещей под капот? Так что я могу писать в любой версии React Fire, но продолжать работать в более низкой среде выполнения.

Я сочувствую вашим опасениям (я также написал свою долю библиотек). Однако, поскольку существует так много компромиссов при изменении чего-либо, мы склонны ошибаться, прилагая усилия для помощи людям в обновлении, а не помогая людям поддерживать несколько версий. Это не значит, что мы вообще этого не делаем (мы выпустили полифилл для авторов библиотек для изменений жизненного цикла в версии 16.3), но мы не оптимизируем для этого варианта использования.

Мое предложение — вырезать новый мейджор, когда мы сокращаем новый мейджор, если что-то несовместимо. Люди могут продолжать использовать старые основные версии вашей библиотеки, если захотят. Я знаю, что поддерживать его требует больше усилий, особенно если вы продолжаете его развивать, но сомнительно, что единая хакерская кодовая база лучше, чем две расходящиеся, но согласованные кодовые базы.

@jamesmfriedman должно быть возможно (и не слишком сложно) обновить (автоматически) с помощью codemod) новый API, а затем (как часть процесса сборки) преобразовать (опять же с codemod) в старый API. Затем отправьте оба пакета и запросите их динамически в зависимости от версии React.

Это некоторая работа, но ее можно выполнить один раз (например, с помощью плагина веб-пакета или скрипта установки npm?) И это не должно быть сложно. Я бы предположил, что это то, что нужно выпустить один раз и использовать во всех библиотеках.

Например, слой совместимости времени компиляции специально для библиотек.

Я поддерживаю отказ от htmlFor for for.

Как вы думаете, будет ли хорошей идеей выпуск моста, который поддерживает как className, так и class? Это позволит разработчикам использовать старый сторонний код React, в то время как их текущий собственный код может быть ориентирован на будущее. После того, как третья сторона обновится, можно просто удалить пакет моста, чтобы получить полностью оптимизированный React DOM.

React API остается непоследовательным и нарушает дальнейшие предположения (почему htmlFor не для и т. д.)

Я думаю, вы пропустили последнее предложение, когда я сказал, что for также следует изменить. Тогда я думаю, что мы будем полностью соответствовать «именам атрибутов в верблюжьем регистре», за исключением одного или двух редких атрибутов SVG. Что мы тоже можем изменить.

Разве не было плагина Babel для обработки всей ситуации «class v className» / «for v htmlFor»?

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

const props = {
   class: "foo"
}
<div {...props} />

Также не имеет смысла передавать class , но получать className в свойствах компонента. Или, если плагин нацелен только на элементы платформы, было бы странно, если бы замена button на Button изменила то, во что компилируется реквизит class .

Использование для этого плагина Babel просто затемняет семантику кода, который вы пишете, и приводит к еще большей путанице. На мой взгляд, это худшее решение, чем разрешение только className или class .

Забавный факт: так работала очень старая версия компилятора JSX. Это поведение было удалено из-за его запутанности.

Потрясающие изменения. . .

Удивительно! Спасибо всем участникам за работу, чтобы принести такие интересные обновления.
Я понятия не имел, что className > class вызвало такой большой скандал. Лично я уже привык.

Уменьшенный размер пакета и обновленная система событий звучат многообещающе. Супер в восторге!

Я действительно с нетерпением жду разделения полифиллов системы событий на отдельные пакеты.
Но будь className > class слишком радикальным, вы знаете, React имеет слишком широкое влияние.
Приведет ли это к непредвиденному для многих систем?

Было бы неплохо отказаться от трети React DOM.

Будет здорово использовать React в разработке веб-приложений.

Также было бы неплохо, чтобы пространство имен реагировало на определенные реквизиты, такие как key и ref . например

<Foo @key="foo" @ref={callback} prop="hi" />

это обсуждалось здесь - https://github.com/facebook/jsx/issues/66

@elado Хотя это может быть чем-то, что мы хотим сделать в будущем, я думаю, что это выходит за рамки, потому что это влияет на API, не зависящий от DOM.

Хотя это интересно, особенно уменьшение размера пакета, что всегда приветствуется. Меня беспокоит то, что люди в Facebook недооценивают инерцию, боль и фрагментацию, разрушающие изменения API, которые могут причинить экосистеме и сообществу.

Это правда, что у них есть большое количество компонентов в FB, о которых нужно беспокоиться, но преимущество, которое они получили, и я предполагаю здесь, заключается в их минимальной зависимости от внешних библиотек реагирования с открытым исходным кодом, поскольку они, скорее всего, создали большинство своих компонентов внутри. Для других людей, которые используют много библиотек с открытым исходным кодом, действительно потребовались большие усилия, ожидание и разочарование, чтобы получить Proptypes из многих библиотек (и я говорю из реального опыта обновления большой базы кода реакции). Быстро двигаться и ломать вещи может быть неприменимо для людей, которые хотят построить стабильный бизнес с ограниченными ресурсами.

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

Помимо этого, я очень ценю усилия по созданию, поддержке и обновлению React, а также энтузиазм инженеров, стоящих за ним :)

Эти будущие {...обновления} 🔥

className -> class : я не думаю, что это редкая ситуация, когда атрибут класса определяется вне объявления JSX/объекта. В таких ситуациях нам придется использовать разные имена для одного и того же объекта, что приведет к несогласованности, увеличению сложности кода и когнитивной нагрузки.
Предлагаемое изменение не устранит несоответствие имени атрибута/реквизита из нашей кодовой базы — оно будет существовать где-то из-за ограничений синтаксиса или при работе с родным DOM. Хорошо, что у нас есть «стандартизированный» (и хорошо зарекомендовавший себя на данный момент) обходной путь для этой проблемы с именами.
В настоящее время className можно использовать последовательно везде, всегда ссылаясь на одно и то же — даже при работе с нативным DOM. На самом деле реакция может быть буквально единственным местом, где мы будем вынуждены использовать class для ссылки на атрибут класса.
className с самого начала казались совершенно ненужными и немного запутанными, но позже оказались довольно практичными и к ним относительно легко привыкнуть.

Я бы также избавился от лишнего объекта { __html } за dangerouslySetInnerHTML , поскольку он кажется действительно ненужным, но, возможно, он не стоит проблем, связанных с миграцией (и, возможно, вообще не связанных с этой проблемой).

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

Чем больше критических изменений, тем больше времени потребуется для обновления реальных пользовательских приложений. Лично я уже довольно сильно отстал от последнего величайшего React (что меня огорчает), потому что в предыдущих версиях React были сломанные вещи, которые затем требуют обновлений библиотек, от которых я зависим, что затем приводит к задержке.

В идеале я хотел бы быть в сценарии, который:

  • Библиотека Downstream React переписывает код в новой версии, внося ошибку для моего варианта использования
  • React добавляет классную новую функцию / сокращение пакетов
  • Старая версия библиотеки остается пригодной для использования в новом React
  • Да, я могу использовать новую функцию сразу после запуска React и просто ждать, пока библиотека исправит ошибку.

На практике это больше похоже на:

  • Библиотека переписывает код, внося ошибку
  • React выпускает новое критическое изменение
  • Старая библиотека больше не работает
  • Новая библиотека со временем обновляется
  • Баг все еще может присутствовать
  • Я застрял на устаревшем React, а не (цитируя Кена Уилера) на «новой моде» на долгое время.
  • Мне грустно :(

С точки зрения «поставочного кода» каждое крупное критическое обновление становится огромной частью надоедливого технического долга, который включает в себя обновление всех зависимостей, повторное тестирование всего, а затем поиск новых ошибок, чтобы увидеть, есть ли обходной путь. Если нет критической уязвимости или действительно нецелесообразно что-то делать (и эта планка высока), приоритет теряется.

К сожалению, несмотря на отказ от парадигмы 0.x и попытки стать основной веб-библиотекой, React по-прежнему постоянно обновляет номера версий, а это означает, что много времени тратится на работу, чтобы стоять на месте.

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

(Кроме того, IE11 печален, потому что вы отказываетесь от браузера, который не является EOL — последний выпуск был выпущен 52 дня назад. Я думаю, что команда React обнаружит, что это просто перекладывает работу на команду Facebook и все внешние и внутренние библиотечные команды, чтобы смягчить это. вместо).

@urugator

Я бы также избавился от дополнительного объекта { __html } дляhazardlySetInnerHTML, поскольку он кажется действительно ненужным.

Это намеренно разработано, чтобы быть явным и трудным для случайного использования. Если его удалить, любые непроверенные данные могут быть случайно переданы вопасноSetInnerHTML.

@philipwhiuk

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

Критические изменения необходимы для улучшения технологии, и React делает это ответственно, выпуская нечастые партии критических изменений. Без критических изменений, таких как удаление componentWillReceieveProps, у нас не было бы замечательных вещей, таких как React Suspense, и программное обеспечение в сообществе было бы сложнее поддерживать, а старые API оставались бы навсегда. Если вы обновляете одну основную версию за раз, все будет в порядке.

Кроме того, IE11 печален, потому что вы осуждаете браузер, который не является EOL - последний выпуск 52 дня назад.

Никто не осуждает IE 11. Текущая версия React фактически требует полифиллов для некоторых функций в IE 11, поэтому предлагаемые изменения, вероятно, окажут примерно такое же влияние на разработку IE 11. https://reactjs.org/docs/javascript-environment-requirements.html

Я бы также избавился от дополнительного объекта { __html } дляhazardlySetInnerHTML, поскольку он кажется действительно ненужным.

@urugator — Как бы то ни было, внутри Facebook наиболее распространенное использование __html — это вставка HTML-кода, отображаемого сервером, в дерево компонентов React. Для этого варианта использования мы создаем объекты __html на стороне сервера, и у нас есть правила lint, запрещающие делать это на стороне клиента. На стороне сервера у нас есть методы, которые сериализуют XHP в объекты со свойствами __html . Это гарантирует, что мы нигде не создадим никаких дыр в безопасности, поскольку XHP очень похож на JSX (на самом деле он был основным источником вдохновения для JSX), а также имеет защиту от XSS.

По сути, объекты __html отмечают строку HTML, которая, как мы знаем , была где- то очищена и ее можно безопасно вставить непосредственно в DOM. С необработанной строкой сложнее работать. Как узнать, была ли она очищена или кто-то случайно вернул какой-то необработанный пользовательский ввод (и, таким образом, ввел дыру XSS)?

Так что да, его намеренно сложно использовать, потому что в большинстве приложений не должно быть много вариантов использования, и варианты использования должны быть разумно ограничены. Как правило, вам не следует создавать объект __html непосредственно в вашем компоненте React, вместо этого у вас должна быть некоторая функция, которая его возвращает (посмотрите, как в документации используется функция createMarkup : https://reactjs. org/docs/dom-elements.html#dangeroussetinnerhtml)

Меня беспокоит то, что люди в Facebook недооценивают инерцию, боль и фрагментацию, разрушающие изменения API, которые могут причинить экосистеме и сообществу.

Спасибо, что подняли этот вопрос. Я прекрасно понимаю, откуда ты. Но я хотел бы отметить, что большинство людей в команде React сами использовали React за пределами Facebook до того, как их наняли — часто в больших приложениях. Поэтому я думаю, что это помогает нам сопереживать тем проблемам, которые затрагивают наших пользователей с открытым исходным кодом. Я использовал React в течение двух лет и очень хорошо помню фрагментацию, вызванную, например, переключением контекста родитель/владелец. Ключом к успеху была хорошая стратегия миграции — и то же самое относится ко всем вышеперечисленным изменениям.

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

Это исторически было верно для продуктовой стороны разработки. Однако с тех пор, как Yarn был создан и интегрирован с нашим веб-репозиторием, мы стали свидетелями увеличения числа сторонних компонентов, используемых на внутренних страницах инструментов, которые сами по себе имеют гораздо большую площадь поверхности, чем потребительские продукты Facebook. Так что нам понадобится стратегия постепенной миграции и в сторонних пакетах.

В отличие от многих других компаний, мы используем одну и ту же версию React во всей кодовой базе. Таким образом, у нас также есть уникальные проблемы (например, мы не можем просто «ждать» с обновлением некоторых продуктов). Это, безусловно, усилит давление на нас, чтобы мы разработали хорошую стратегию миграции, и послужит стресс-тестом.

Для других людей, которые используют много библиотек с открытым исходным кодом, действительно потребовались большие усилия, ожидание и разочарование, чтобы получить Proptypes из многих библиотек (и я говорю из реального опыта обновления большой базы кода реакции). Быстро двигаться и ломать вещи может быть неприменимо для людей, которые хотят построить стабильный бизнес с ограниченными ресурсами.

Если вам интересно, у нас все еще есть код вроде

React.PropTypes = require('prop-types')
React.createClass = require('create-react-class')

в нашей кодовой базе, потому что мы также не можем позволить себе полностью перейти на «чистый лист». Но люди, которые сегодня начинают работать с React, а также с более современными частями нашей кодовой базы, не должны нести этот груз. Вот как мы думаем об этом — мы хотим выбрать лучшие значения по умолчанию для новых пользователей React, но иметь хорошую историю миграции для себя и всех остальных, даже если некоторые ее части могут быть хакерскими.

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

(Кроме того, IE11 печален, потому что вы отказываетесь от браузера, который не является EOL — последний выпуск был выпущен 52 дня назад. Я думаю, что команда React обнаружит, что это просто перекладывает работу на команду Facebook и все внешние и внутренние библиотечные команды, чтобы смягчить это. вместо).

Я не понимаю, что вы имеете в виду. Я нигде не говорил, что IE11 устарел.

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

Кроме того, мы не можем «перекладывать работу» на другие команды в Facebook. Если мы что-то сломаем, мы должны это починить. Вот почему мы так заботимся о стратегиях миграции — обычно нам приходится выполнять их самостоятельно.

Re: остальная часть вашего комментария — мы абсолютно не делаем критических изменений ради этого. На самом деле мы очень, очень стараемся избежать критических изменений. Есть много частей React, которые сложны и трудны в обслуживании, но мы сохраняем их по той единственной причине, что пытаемся поддерживать устаревшие API, даже если они явно помечены как нестабильные. Однако в какой-то момент масса проблем накапливается, и нам нужно очистить доску, чтобы двигаться вперед и исправить их. Проблемы в моем посте ОП - это именно такие проблемы. Им не стоило бы вносить критические изменения в одиночку. Но в совокупности, мы думаем, они того стоят.

Я не понимаю, почему люди так негативно к этому относятся. Просто не обновляться, пока не обновятся ваши зависимости?

Является ли проблема с ключевым словом для class против className и for против htmlFor не тем, с чем компилятор jsx может справиться, чтобы переопределить зарезервированные слова?

Я действительно был бы обеспокоен только тем, что изменения достаточно велики, чтобы результаты поиска давали устаревшие ответы... Как и боль angular 2+, представленная при поиске в Google "angular -angularjs -angular1.x" и т. д.

В остальном приветствую все изменения!!!

@gaearon

Ты сказал

«Возможно, нам придется отказаться от совместимости с некоторыми старыми браузерами»

У меня была проблема с совместимостью с отбрасыванием, а не со следующей частью полифилла. Меня беспокоило возвращение в темные века.

Касательно процесса. Разве не для такой «проблемы» был разработан процесс RFC?

У меня была проблема с совместимостью с отбрасыванием, а не со следующей частью полифилла. Меня беспокоило возвращение в темные века.

Я говорил о IE10 и более ранних версиях. Я специально отметил, что мы хотим продолжать поддерживать IE11 — я думаю, что он составляет около 3% нашего трафика, что намного больше, чем ограничение в 1%, когда мы считаем его слишком устаревшим.

Касательно процесса. Разве не для такой «проблемы» был разработан процесс RFC?

Мы опубликуем RFC, когда все будет более подробно. Многое из этого требует исследований, экспериментов и фактического тестирования, чтобы определить, что мы можем и чего не можем делать, и какие стратегии миграции мы могли бы использовать. Сейчас у нас недостаточно деталей, чтобы даже начать думать о RFC (которые должны включать комплексную стратегию миграции).

Ок спасибо за разъяснение!

@gaearon

Вполне вероятно, что мы вообще избавимся от синтетических событий.

Как это будет работать, если event.currentTarget указывает на элемент, к которому подключен прослушиватель событий, что в нативном случае всегда означает document — или корень React, когда React переключается на него?

React — это не просто установка свойств

(...)

Я хочу сказать, что то, использует ли React свойства или атрибуты внутри, является деталью реализации.

Почему это деталь реализации, если она может влиять на то, что происходит в DOM? Если только это не относится только к свойствам, которые каким-то образом отражаются в атрибутах (и обратно), например class / className .

Я чувствую, что путаница с обработкой class / className связана с тем фактом, что использование React свойства или атрибута считается деталью реализации. У меня есть опыт работы с Angular, и когда я начал использовать React, это было для меня самой большой проблемой — в Angular разделение между атрибутами, свойствами и обработчиками событий ясно из синтаксиса, и я был сбит с толку тем, установлены ли реквизиты для элементов DOM React как свойства или атрибуты.

Как это будет работать с event.currentTarget, указывающим на элемент, к которому прикреплен прослушиватель событий, что в нативном случае всегда означает документ или корень React, когда React переключается на него?

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

Почему это деталь реализации, если она может влиять на то, что происходит в DOM? Если только это не относится только к свойствам, которые каким-то образом отражаются в атрибутах (и обратно), таких как class/className.

Для большинства из них нет заметной разницы с точки зрения пользователя, какой из них использовать. Я думаю, что большинство из них отражены (хотя, может быть, я ошибаюсь).

У меня есть опыт работы с Angular, и когда я начал использовать React, для меня это была самая большая проблема — в Angular разделение между атрибутами, свойствами и обработчиками событий ясно видно непосредственно из синтаксиса, и я был сбит с толку, устанавливаются ли реквизиты для элементов DOM React как свойства или атрибуты.

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

( Есть случаи, когда это становится гораздо более актуальным, например, с пользовательскими элементами. Но даже в этом случае поддержка обоих одинаково сбивает с толку, потому что вы должны выбрать, какой из них использовать. Это обсуждалось в другом месте, поэтому я хотел бы избежать прыжков. снова в эти дебаты — у нас есть предложения от таких людей, как @robdodson , и мы их рассмотрим.)

@Daniel15
Без упомянутых политик (которые, я думаю, больше нигде не упоминаются) дополнительная оболочка объекта никоим образом не делает его более безопасным.
Я считаю, что пользователь достаточно предупрежден об опасном использовании через dangerouslySetInnerHTML . Это момент, когда пользователь вынужден проверить документы, обдумать последствия и принять решение.
Необходимость обернуть (возможно, непроверенную) строку в какой-либо объект/функцию не заставит его пересмотреть или продезинфицировать обернутое значение.
Если бы это работало таким образом, то, возможно, { __html } не было бы достаточно сложным, а [{ _html: { __html }] сделало бы его еще безопаснее - сколько раз мы должны заявить, что что-то опасно, чтобы сделать его безопасным. ?

С тем пониманием, которое вы предоставили, я понимаю рассуждение, но я думаю, что в настоящее время оно не применяется ни к кому за пределами Facebook, потому что мы понятия не имеем о правиле « { __html } представляет очищенный html».
Я всегда думал, что это просто еще одно препятствие в API. Спасибо, что нашли время и пролили свет на это, теперь это имеет больше смысла.

Речь идет не только об усложнении, но и о предотвращении случайного использования непроверенных данных.

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

Мне нравится, что все думают, что изменения, которые появятся здесь или появились в React в последних версиях, были «ломающими». Эти люди явно не сталкивались с Angular 2 > 3 > 4 раза.

Я люблю изменения. Лично я не возражаю против className , и деструктуризация class может стать проблемой. Но я хотел бы посмотреть, что вы, ребята, собираетесь придумать.

Прошу вести дискуссию по теме. Считаете ли вы заражение опасного HTML полезным или нет, это интересно, но не связано с проблемой.

я люблю Реакт

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

Просто позволение людям использовать class не имеет негативных последствий, за исключением того, что это не работает с деструктурированием и затратами на миграцию.

@gaearon Добавление 2c, но эти два минуса кажутся такими же большими или большими, чем текущий минус (единовременная небольшая стоимость обучения class => className по сравнению с постоянным предотвращением деструктуризации + затраты на миграцию на уровне экосистемы).

Реагировать :heart:

повторяя @natew выше:

@gaearon Добавление 2c, но эти два минуса кажутся такими же большими или большими, чем текущий минус (единовременная небольшая стоимость обучения class => className по сравнению с постоянным предотвращением деструктуризации + затраты на миграцию на уровне экосистемы).

В любом случае, какова мотивация перехода с className на class ?
Насколько я понимаю, ваш комментарий сводится к двум аргументам (пожалуйста, поправьте меня, если я ошибаюсь):

ближе концептуально к тому, что ожидает большинство людей

Хорошо, но добавление Name — это самое маленькое препятствие. Научиться использовать className было самой простой частью изучения React. Это небольшая причуда, у которой нет недостатков — она фактически решает проблему с четырьмя персонажами. И у него намного меньше когнитивных издержек, чем у любой из предложенных альтернатив деструктуризации.
Представьте, что вы учите кого-то стилизовать свой первый компонент React с помощью

function Button({ color, ...rest }) {
  const buttonClass = rest.class +  ' Button-' + color;
  return <button {...rest} class={buttonClass} />
}

Моя голова нуба взорвалась бы.
Я думаю, что при взаимодействии с API люди ожидают, что API предоставит решения. ClassName — это встроенное решение. Класс — это встроенная проблема.

меньше печатать

Брух, это четыре символа 8^) . Кроме того, даже если мы деструктурируем class гораздо реже, чем в настоящее время используем className , при этом приходится печатать гораздо больше. Итак, я буду вводить на 4 символа меньше 12 раз, но добавляю еще 50 символов каждый раз, когда я разрушаю class ? Это просто глупо.

Есть ли еще одна веская причина для этого изменения, которую я пропустил?
Является ли мотивация какой-то заботой о соответствии атрибутам/свойствам DOM?
Мне это кажется слишком академическим аргументом. Большинство людей не очень хорошо осведомлены об этих деталях реализации, и я не думаю, что они должны быть осведомлены.

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

И если бы React использовал класс с самого начала, мы бы привыкли к деструктурированию класса и переназначению его на className, но любой, кто придет с PR для изменения класса _to_ className, будет провозглашен спасителем.

Наконец, я просто хочу сказать, что не ожидал, что меня это так расстроит, поэтому прошу прощения, если что-то покажется грубым, оскорбительным или обвинительным. Я благодарен за всю работу, которую вы проделываете над React, и за все знания, которые вы даете в Twitter — я использовал ваши твиты, чтобы защитить некоторые ответы, которые я дал в интервью.

Я молюсь dan.church , чтобы вы передумали.

Я очень рад, что React можно постоянно обновлять. Как разработчик, использующий React, я не хочу, чтобы его обогнал Vue. Но процесс className-> class должен быть болезненным.

Я не против переименования className -> class ради копипаста, но на данный момент для этого нет четкой мотивации. className существует в DOM, в то время как есть зарезервированные имена свойств, которые появляются из ниоткуда, например, htmlFor . Я чувствую, что они должны быть приоритетными, когда дело доходит до переименования, и это, вероятно, менее распространенное изменение, которое также может служить проверкой.

@sonhanguyen htmlFor также является официальным именем веб-API: https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor .

@allan2coder вместо того, чтобы оборачивать его в массив, оберните его в <React.Fragment> или <> .

@allan2coder Также, пожалуйста, давайте поддерживать эту ветку по теме, вы можете задавать вопросы, отправив отдельную проблему, если хотите.

Я хотел бы обратить внимание на пакет patch-package , который упрощает исправление ваших зависимостей (например, чтобы они перестали использовать неподдерживаемые API React). По общему признанию, это более полезно для кода приложения, чем для кода библиотеки, но я думаю, что это должно помочь решить некоторые проблемы @philipwhiuk .

Я с нетерпением жду.

  • Перейдите с onChange на onInput и не используйте полифиллы для неконтролируемых компонентов.

Что касается приведенных выше слов, мне любопытно, будет ли событие onChange использоваться близко к собственному событию или не будет использоваться в будущем?

@MuYunyun

Судя по формулировке, они не планируют сохранять текущее поведение onChange. Это не имело бы особого смысла. React, как и другие современные библиотеки, не будет уровнем совместимости браузера и не должен им быть.

Текущий onChange эмулирует ввод + несколько других случаев. Это вообще не имеет смысла, учитывая, что событие изменения уже существует в DOM и не имеет такой же семантики: https://developer.mozilla.org/en-US/docs/Web/Events/change .

@jxub

Немного оффтоп, но это немного грустно, что никому (насколько я знаю) не пришла в голову идея сделать трансформер html/css/svg -> jsx, чтобы упростить миграцию в React с таким количеством тривиальных изменений для сопоставления атрибутов HTML с Реагируйте на реквизиты. Столько человеко-часов потрачено впустую, в основном на поиск и замену :(

Я не знаю о других редакторах, но IntelliJ IDEA (и WebStorm, PhpStorm и т. д.) делает это преобразование, когда вы вставляете HTML-код в JS.

Немного оффтоп, но это немного грустно, что никому (насколько я знаю) не пришла в голову идея сделать трансформер html/css/svg -> jsx, чтобы упростить миграцию в React с таким количеством тривиальных изменений для сопоставления атрибутов HTML с Реагируйте на реквизиты. Столько человеко-часов потрачено впустую, в основном на поиск и замену :(

Он действительно существует, но довольно старый и не совсем правильный: https://magic.reactjs.net/htmltojsx.htm .

Мы должны возродить это усилие. Если вы хотите помочь, сделайте это: https://github.com/reactjs/reactjs.org/issues/484. Пока никто не предложил помощь и не ответил.

Он действительно существует, но довольно старый и не совсем правильный: https://magic.reactjs.net/htmltojsx.htm .

Я использовал это множество раз раньше — это очень распространено при передаче определенных компонентов на аутсорсинг людям, которые знают HTML/CSS, но не знают JavaScript.

Так что просто оставляю отзыв о том, что это полезный инструмент, который люди используют на практике. В сети есть и другие конвертеры.

Проблема с этим подходом заключается в том, что он только односторонний (только миграция _to_ реакция). Однако эта проблема не является особенной для React.

Надеюсь, это сильно упростит задачу...

Проблема с этим подходом заключается в том, что он является только односторонним (только миграция для реагирования). Однако эта проблема не является особенной для React.

Почему? Наоборот, должно быть еще проще — просто запустите ReactDOMServer.renderToString .

Терпеливо ждем релиза

@gaearon

Почему? Наоборот, должно быть еще проще — просто запустите ReactDOMServer.renderToString.

Итак, для контекста обсуждаемая проблема такова: я хочу, чтобы люди, которые пишут html/css и недостаточно хорошо знают JavaScript, могли работать с кодом JS, чтобы иметь возможность работать с разметкой/стилем/макетом компонентов.

Один из способов сделать это прямо сейчас — попросить их разработать его в html/css и использовать htmltojsx. Это работает очень хорошо для меня.

Проблема в том, что теперь я должен сам поддерживать каждое изменение разметки/стиля/макета в React.

Если я действительно вызову ReactDOMServer.renderToString , я выведу статический HTML, но в этом HTML будет отсутствовать весь фактический код компонента, поэтому невозможно передать его людям с пользовательским интерфейсом и использовать их вывод, поскольку мне придется переписать все моя логика.

Такие вещи, как react-sketchapp, являются хорошим возможным решением проблемы, но я надеюсь на более общий подход, позволяющий мне делать это при использовании обычного html/css. Например, через некоторую форму метаданных и сохранение идентификаторов реакции на элементы.

Я полностью понимаю, что это не относится к ядру ReactDOM, но оно определенно находится в его области и представляет собой интересную проблему.

Это не имеет высокого приоритета — я просто хотел объяснить, почему htmltojsx полезен для некоторых из нас даже вне контекста миграции :)

Я хочу, чтобы люди, которые пишут html/css и недостаточно хорошо знают JavaScript, чтобы работать с кодом JS, могли работать над разметкой/стилем/макетом компонентов.

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

Извините, если это слишком не по теме, но я считаю, что в наши дни просто HTML/CSS недостаточно.

( @gaearon не стесняйтесь скрывать это, если будет шумно, так как это ответ на вышеупомянутый уже незначительный комментарий ОТ)

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

Ну, для этого потребуется следующее:

  • Работайте только с подрядчиками, знакомыми с вашим текущим стеком React. Гораздо сложнее найти людей, которые будут изучать стилизованные компоненты.
  • Установите Node (npm), ваш стек (React, webpack и т. д.) и все остальное, необходимое для запуска этого проекта на каждом компьютере пользователя пользовательского интерфейса и поддерживайте его в актуальном состоянии.
  • Научите их основам программирования и JavaScript, научитесь работать с инструментами разработки, ошибками консоли и т. д.
  • Научите их React, каков его синтаксис, такие вещи, как className , что означает key и т. д.
  • Работайте только с подрядчиками и фрилансерами, которые готовы работать таким образом, а не создавать HTML/CSS. Это обычно также делает вещи более дорогими.

Теперь, как упоминалось выше, такие вещи, как react-skeptchapp, являются полезным способом сделать это более доступным и простым для людей, занимающихся пользовательским интерфейсом, но это все еще требует от них многого обучения.

Я полностью понимаю, почему вы спрашиваете об этом, и я не уверен, что это распространенная проблема (я подозреваю, что это так). Несмотря на это, я не думаю, что это касается будущего ядра ReactDOM.

Это совсем не по теме :-) Продолжим дискуссию в твиттере или еще где.

«Поведение, которое вы видите, для которого используется инструмент, — это поведение, которое инструмент поощряет»
~ Гэри Бернхардт

То, как используется React, большая часть которого не является частью API React, приводит к большому количеству ловушек, которые приводят к таким обсуждениям, когда все сбиты с толку и разочарованы. Является ли использование зарезервированного ключевого слова, такого как class , плохим из-за javascript, html или самой реакции?

Возвращаясь к изменениям, внесенным в 16.3 (если я правильно помню), библиотека теперь будет вести себя по-другому, принимая любой атрибут, переданный нативным html-элементам, отображаемым vdom. Я совершенно ясно помню, что большая часть моей кодовой базы теперь страдала от ошибок, потому что поведения, которое у нас было при реализации этого явно плохого шаблона

<div {...this.props} />

Так что я должен сказать, что очень разочарован тем, что Дэн предлагает нам продолжать распространять этот ужасный код по всем кодовым базам.

Прежде всего, нет никаких гарантий в содержимом props , но в первый раз нативные html-элементы почти всегда не будут делать то, что от них ожидается, если вы передадите им неправильные реквизиты, однако в то же время считается безопасным распространять родительские реквизиты на дочерние компоненты, но на самом деле это ужасно лениво

<Child {...props} />

const Child = (props) => <div {...props} />

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

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

Мы должны помнить, что jsx построен поверх javascript, и использование «идиосинкразии» javascript в качестве предлога для преднамеренного конфликта с языком при использовании ключевых слов является плохим первым шагом к исправлению API, я бы посоветовал вместо того, чтобы начинать войну против языка вы бы отошли от него полностью

@gaearon Давно! :) (пс. Извините за тл;др вперед)

В любом случае, я просто хотел дать некоторое представление о том, что я узнал из своих собственных приключений. Я сделал свою собственную «голую минимальную» производную React, которую я теперь использую для приложений, критически важных для производительности / функций. Первоначально это был просто забавный побочный эксперимент, но я наблюдал повышение производительности более чем на +300% в реальных случаях для первоначального рендеринга/обновления/удаления, включая многие другие преимущества. Это также без использования объединенного обработчика событий.

IIRC большая часть этого исходит просто из моей собственной библиотеки, обходя всю логику React-props и просто передавая атрибуты прямо в setAttribute, стили прямо в style.setProperty, слушатели прямо в addEventListener и так далее. Таким образом, базовый интерфейс элемента DOM выглядит следующим образом: `{атрибуты: {}, стиль: {}, слушатели: {}, className: "", ...}, он стал более подробным, но теперь интерфейс стал небольшим и тривиальным для реализации и чрезвычайно быстро. Возможно, это слишком экстремально для вас, но мне это очень хорошо послужило.

Что-то, что я тоже делаю, полностью отказываюсь от CSS, все стили встроены. Это намного быстрее, чем вы ожидаете, и имеет множество приятных практических преимуществ, а также снижает стоимость первоначального синтаксического анализа браузера (что на удивление дорого) и сопоставления селекторов, что окупает большую часть накладных расходов. Я могу легко достичь стабильных 60 кадров в секунду и даже больше на моем маломощном ноутбуке даже для сложных иерархий (без обрезки деревьев).

Я предполагаю, что большая часть из этого не очень полезна для вас, но, возможно, там есть что-то интересное. Как бы то ни было, моя главная претензия к HTML+React заключается в том, что пользовательские компоненты React не предоставляют никакого интерфейса для компоновки/позиционирования (и, возможно, в некоторой степени также событий) без обращения к CSS. Проще говоря, если я создаю ButtonComponent, а затем использую его, по умолчанию его нельзя позиционировать или интегрировать в макет без; реализуя внутри него специальную логику, оборачивая его в фиктивный элемент, который можно позиционировать, или предоставляя свойство стиля, которое объединяется со стилями, используемыми для корневого элемента ButtonComponent. Ни один из них не идеален, и объединять стили как есть опасно, так как легко поместить туда стили, которые вы не должны. По сути, проблема заключается в том, что на границах компонентов подмножество доступных свойств должно быть общедоступным (позиционирование/макет) и некоторым внутренним (визуальный стиль).

Еще я делаю разделение между компонентами и контентом/потомками. Например, компоненты DOM не принимают список дочерних элементов, вместо этого он принимает экземпляр содержимого. Экземпляр содержимого реализует логику согласования и отрисовку дочерних элементов, что означает, что у вас могут быть разные реализации для разных целей. Наиболее очевидные варианты использования; в основном статические иерархии против динамически генерируемых детей. Таким образом, статические иерархии, которые составляют большинство, могут быть реализованы с использованием более быстрой и простой логики, тогда как динамически генерируемые дочерние элементы могут иметь настраиваемые стратегии. Это также открывает возможность иметь «компоненты контента», которые можно использовать для интеллектуального управления, например, макетами flexbox без ненужной косвенности.

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

Что-то, что в основном определенно не для вас, но большая особенность моей библиотеки заключается в том, что она в основном предоставляет только минимальный «базовый элемент DOM» для общих целей. Идея состоит в том, что вы можете тривиально расширять/заменять и реализовывать свои собственные низкоуровневые специфические поведения, если вы разрабатываете большой проект с конкретными требованиями/обстоятельствами очень дешево и не прибегая к «хакам», например, если вы очень сильно касаетесь -ориентированный, хотите выполнить специальную обработку стилей и т. д. Это также означает, что разные версии совместимы и могут работать бок о бок, пока ABI один и тот же (изменение должно быть крайне редким и очень простым для исправления). ). Это также означает, что вы можете быть весьма самоуверенным в интерфейсе элемента DOM без необходимости быть всеохватывающим и пытаться решить проблему каждого.

В любом случае, возможно, в основном это просто бессвязность, и я, вероятно, не очень хорошо передаю большинство концепций, но, возможно, есть что-то интересное для вас от кого-то, кто пошел в противоположном направлении. Большая часть из этого, вероятно, не имеет отношения к вам просто потому, что вы нацелены на «простоту», но кто знает :)

Также, пока я не забыл, вас может заинтересовать моя функция objectKeyValueReconcile , специально оптимизированная для чрезвычайно быстрой работы при сравнении предыдущих/следующих реквизитов для сценариев, подобных React. Это ответственно за довольно значительный реальный прирост производительности для меня.

https://github.com/syranide/surgical/blob/master/packages/surgical/private/objectKeyValueReconcile.js

imho я бы отказался от идеи "класса". JSX в конечном итоге умрет.

Что вы думаете о добавлении поддержки событий DOM/окна, не основанных на элементах, в React DOM? Я подозреваю, что с возможным удалением синтетических событий все еще будет какая-то форма сбора/обновления/пакетирования событий. События нажатия клавиш, изменения размера и прокрутки окна являются распространенными сценариями, которые приходят на ум, но, возможно, возможность поддержки большей части/всего списка в https://developer.mozilla.org/en-US/docs/Web/Events будет быть полезным за той же абстракцией.

Это тоже обсуждается в самом старом открытом выпуске #285 😄.

@gaearon

Практический эффект className -> class будет следующим:

({ className }) => <div className={className} />

станет

({ ...rest }) => <div class={rest.class} />

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

@канс

Или это:

props => <div class={props.class} />

Это такой же сложности, как и исходная функция.

Мне понравилось className, потому что класс — это ключевое слово в js, но в любом случае не думайте, что это так уж важно. Я предпочитаю стиль с чем-то вроде гламура, так что это не то, что на меня влияет. Возможно, я использовал className пару десятков раз за последние несколько лет ?? Больше никогда.

Хотя одна мысль, которая пришла мне в голову в пользу class , заключается в том, что большинство людей, которые на самом деле используют className, используют css, и они ожидают модель html/css class . В подавляющем большинстве случаев основная цель этого реквизита — просто связывание с кодом CSS, верно, так почему бы просто не назвать его классом, как ожидает пользователь html/css?

IMO вне кода системы дизайна, действительно идиоматическая разработка React обычно в любом случае не будет использовать className или класс. Когда мне нужно использовать классы для css, они в основном изолированы от нескольких небольших компонентов пользовательского интерфейса. Почти все, что используется на прикладном уровне, относится к более высокому уровню (например, <Columns verticalAlign="center"> или <BodyText /> ).

Поэтому я думаю, мне интересно, облегчит ли переименование с className на class тех людей, которые все равно используют реквизит (легче начать разработку React, переключать контексты, не злиться? и т. д.), почему бы просто не переименовать его?

Уменьшите размер пакета, пожалуйста.

Поскольку это большое, критическое обновление, возможно, мы могли бы также исправить именование жизненного цикла React!

т. е shouldComponentUpdate => shouldUpdate и т. д. Это название просто глупо.

@AlexGalays

Поскольку это большое, критическое обновление, возможно, мы могли бы также исправить именование жизненного цикла React!

т.е. shouldComponentUpdate => shouldUpdate и т. д. Это название нелепо.

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

Методы жизненного цикла являются частью ядра React, и эта проблема касается исключительно реакции.

@ljharb
Упс, действительно!

@сомпиласар
Извините, это просто неуважительная причина (каламбур, ReasonReact исправила имена методов :)). Мы также не добавляем ко всем нашим модулям префикс их имен пакетов, и мы находим их вполне приемлемыми. В любом случае, я перестану говорить об этом, так как react-core выходит за рамки этого выпуска.

Хотелось бы увидеть эти изменения.
Я надеюсь, что они будут реализованы с учетом взаимодействия пользовательских элементов.

Интересно, стоит ли перенести часть обсуждений в отдельные темы на форуме (https://discuss.reactjs.org)? Поскольку проблемы GitHub не объединены в цепочки, как сообщения на форуме, это затрудняет обсуждение нескольких разных вещей в одной проблеме.

Изменение className -> class мне кажется интересным 😺

Смотреть, проекты React 2019 г.

const {
  class: className, // YouKnowIamRight PepeHands
  someFancyProp,
  ...restProps
} = props

Я вижу, что это произойдет наверняка.

Мне очень нравится иметь возможность копировать и вставлять HTML без необходимости изменять className , но в то же время я вижу проблемы, которые может вызвать зарезервированное ключевое слово class .

На данный момент я бы предпочел придерживаться className , если у вас нет серьезных инженерных опасений по этому поводу (не личное предпочтение).

Но это только мое прагматичное мнение.

Хотя я понимаю дополнительное трение, связанное с невозможностью уничтожить идентификатор class , я чувствую, что слишком много людей в этой теме переоценивают количество раз, которое им нужно получить имя класса в качестве опоры.

Передача className в компонент React (который не является просто элементом DOM) означает, что вы либо создаете довольно небольшие строительные блоки без предоставления каких-либо новых абстракций, либо этот компонент раскрывает некоторые детали своей реализации. В первом случае (например, компонент <Button /> ) вы, вероятно, захотите последовать примеру @gaearon и также перенаправить «остальные» реквизиты в элемент DOM. Во втором случае, возможно, дополнительное трение заставит вас не делать этого и найти лучшее решение.

По моему скромному опыту, мне приходилось копировать и вставлять HTML в JSX (и заменять class на className ) больше раз, чем я могу вспомнить создание компонента, который получает className .

Распространение всех реквизитов в HTML — это анти-шаблон. Если кто-то в будущем добавит дополнительную поддержку, которая соответствует атрибуту HTML, это неожиданно изменит поведение. Если IE добавит новый атрибут, вы обречены.

@philipwhiuk , если вы распространяете только тот реквизит, который не используете, проблем с поведением не будет.

@j-f1

если вы будете распространять только тот реквизит, которым не пользуетесь, проблем с поведением не будет.

Не совсем. Если вы добавите новый параметр в API вашего компонента, этот параметр перестанет передаваться базовому узлу DOM. Кто-то может зависеть от того, что именно этот атрибут установлен для элемента, и тогда вы сломаете этого человека. Распространение всех неиспользуемых реквизитов на что-либо ниже означает, что любое дополнение к API вашего компонента является критическим изменением.

Кстати, я использовал случайный пример, в котором вы деконструируете значение class , но не обрезаетесь на этой детали.

Многие из вас (да, вы делаете) деконструируют почти каждое значение из props и state вместо того, чтобы использовать точечную нотацию без каких-либо причин, кроме того, чтобы избежать ввода лишнего текста.

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

Если бы вы были немного более прагматичны, вы бы говорили о технических последствиях, а не о своих личных предпочтениях, но я не вижу, чтобы кто-нибудь говорил что-либо о технических последствиях className .

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

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

Но опять же, мое прагматичное мнение.

Говоря о полифиллах, я не думаю, что реакция должна пытаться определить, указал ли пользователь «хорошие» полифиллы.
(например, hasBadMapPolyfill в коде)
React не должен нести ответственность за все случайные ошибки, которые можно допустить в проекте программирования.

@AlexGalays React полагается на использование реализации карты с правильной семантикой. Если пользователи используют несовместимый полифилл, их приложение может сломаться неожиданным и запутанным образом, поэтому в этом случае полезно предупредить заранее.

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

Мне нравится этот React Fire, и вы бы продолжили работу над этим, так как это кажется более интересным шагом по модернизации ReactDOM.

Возможно ли, чтобы реагирующий огонь не перепривязывал обработчики событий?

class Compo exntends Compoent {
 onClick() {
   ...
 }
  render() {
   <button onClick={this.onClick} >click me </button>
  }
}

Я не думаю, что кто-то на самом деле хочет, чтобы обработчик событий был восстановлен. И в тех редких случаях, когда вы хотели бы, вы можете связать его вручную.

@куллофид

Возможно ли, чтобы реагирующий огонь не перепривязывал обработчики событий?

Вы можете привязать метод к классу один раз, используя автоматические привязки стрелочных функций или привязав функцию в своем конструкторе. Если есть уникальные параметры, которые вы хотите связать с событием, вы можете заглянуть в запоминание обработчиков событий или прикрепить атрибуты DOM к самим узлам и получить к ним доступ через event.currentTarget .

class Compo extends Compoent {
 onClick = () => {
   ...
 }
 render() {
   <button onClick={this.onClick}>click me</button>
 }
}

Еще одно преимущество упрощения системы событий (можем ли мы вернуться к необработанным событиям DOM без какого-либо пула, как это делают ВСЕ фреймворки? :)) заключается в том, что также легче статически типизировать.

Кажется, отличный план! Было бы очень приятно иметь поддержку IE 11 (даже если это означает поставку наших собственных полифилов, что совершенно нормально). Как человек, работающий с государственными клиентами, когда они перестанут использовать IE 11, совершенно неизвестно :(

@MatthewHerbst та же самая лодка, наши клиенты используют IE 11, и у нас достаточно трафика 😢

Просто хотел вмешаться, чтобы сказать, что все это супер захватывающе. Единственное, что я прочитал, что меня обеспокоило:

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

Сейчас мне нравится знать, что система событий React будет «просто работать» в любом браузере, который поддерживает React. Я боюсь, что это изменение будет означать, что приложение станет обязанностью учитывать кроссбраузерные проблемы. Это, вероятно, приведет к появлению множества трудно отслеживаемых ошибок. ... по крайней мере, для моих приложений. :)

В любом случае, спасибо, как всегда, за отличную библиотеку.

@kentcdodds упомянул интеграцию JSX 2.0 как возможную идею, которую я читал в Стратегии и не видел ничего, что казалось бы связанным с этим. Мне было интересно, это было просто в воздухе или что-то, что будет отложено на будущее?

Пусть IE умрет! Не поддерживайте абсолютно устаревшие браузеры. Нет причин, даже для ограничительных компаний, не переходить на современный браузер. Вы будете видеть этот IE11 в своей статистике до тех пор, пока вы и Интернет не перестанете его поддерживать.

@hbroer Устаревшее программное обеспечение?

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

  • "не знаю, как обновить" - не наша проблема, но мы можем вставить в сообщения "установить новый браузер" со списком браузеров и, возможно, со справочным текстом и номером телефона горячей линии Microsoft ^^
  • «нет выбора» — правильно, но организация должна обновить свою среду. Если их инструменты не работают, они сработают.

Я ненавижу программировать для прошлого и не могу использовать преимущества новых технологий, потому что 90% кодеров до сих пор поддерживают дрянные браузеры 15% нижних потребителей, живущих в прошлом веке. ^^ Не хочу, чтобы в течение следующих 10 лет снова возникало это «о, что с этим интернет-эксплорером 6 ботаников, мы должны поддерживать эти 15%».

Кстати, M$ собирается вывести Edge для Windows 7 и 8 с переходом на webkit.

@hbroer все это наша проблема, если это влияет на пользователей. Имейте некоторое сочувствие к другим людям.

(Отдельно, M$ — довольно юношеская и очень устаревшая отсылка к концу 90-х, которую вы, возможно, захотите удалить; я буду рад удалить это в сторону, если вы это сделаете)

Вижу, тут много фанатов M$. :DI действительно заботятся о людях, а не об организациях, которые блокируют развитие технологий, или о кодерах, которым приходится годами поддерживать это старое дерьмо. У меня нет проблем с дополнительным пакетом, который делает библиотеку «совместимой со старым дерьмом». Но библиотека в 2019 году должна быть написана с учетом >= технологий 2019 года, а не <= технологий 2013 года. Это достаточно плохо, чтобы поддерживать это (о, давайте сделаем это немного по-другому) сафари и (старое) дерьмо края.

микрокапля

@hbroer на самом деле древний браузер Android и древнее сафари представляют большую проблему, чем любой браузер Microsoft. речь идет не о том, чтобы быть «фанбоем», а о том, чтобы быть профессионалом, а использование термина «M$» — нет.

И нет, поддерживать старые технологии никоим образом не «плохо», это морально и этично. Что плохо, так это веб-сайты, которые «лучше всего работают в X», будь то Netscape Navigator, IE 6 или последний Chrome.

Вижу, тут много фанатов M$.

@hbroer Я вижу здесь человека с массовыми атаками ad hominem.

Но библиотека в 2019 году должна быть написана с учетом >= технологий 2019 года, а не <= технологий 2013 года.

Нет, не должно.

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

Как только вы наберете достаточное количество пользователей, IE11 станет значительной частью людей, которые заходят на ваш сайт. На предыдущей работе у нас было около миллиона человек в месяц, заходящих на наш сайт из IE11.

browsers

Если вы хотите поддерживать старое дерьмо, добавьте поли заливки. Нет причин не кодировать будущее и настоящее. Поддержка старых технологий делает веб-приложения более жирными и медленными, чем необходимо.

Ps я вижу человека, который не умеет читать сарказм и ему плевать на смайлики ^^

@hbroer Вы показываете, что IE11 присутствует, поэтому ожидается, что мы будем кодировать его.

И еще раз. См. значение по умолчанию на странице https://browserl.ist.

Ps я вижу человека, который не умеет читать сарказм и ему плевать на смайлики ^^

Да, нет. Это обычная тактика, используемая троллями и хулиганами на игровых площадках. «Что?! Я тебя не оскорблял! Это была просто шутка!».

0,20% населения планеты, даже с учетом «тех, кто пользуется интернетом», составляет 6,4 млн человек. Проценты совершенно не важны. Код для людей; прошлое и будущее, а также размер вашего пакета не имеют значения.

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

Теперь, в 2019 году, я буду использовать для новых проектов сетку css (которая имеет только экспериментальную поддержку в IE11) и будет транспилироваться в ES6, и я не хочу создавать полифиллы для этого устаревшего браузера. Пользователи IE11 просто получают сообщение: обновите свой браузер или используйте альтернативный.

Есть люди, которые не хотят использовать java script. Вы заботитесь о них? Вы не видите, что ребята в статистике. И я тоже не в статистике, как и многие другие люди, которые блокируют эти инструменты.

Я смотрю на каждый браузер, который не устарел. Я поддерживаю Edge, у которого меньше пользователей, чем у этого дерьма IE11, из-за Windows 7 (которая поддерживает конец января 2020 года), и современные люди используют современные браузеры. ^^

Никто не запрещает вам использовать полифиллы и что-то вроде пакета совместимости. Но ядро ​​должно быть обновлено и не отставать только из-за одного куска старого технологического браузера M$.

Чего мне не хватает во многих фреймворках javascript, так это LTS. Вот о чем мы можем говорить. Если вы создаете современную страницу с функциями из настоящего, то было бы неплохо использовать современную технологическую структуру. И если вы создаете веб-приложение для b2b, которое требует максимальной стабильности и совместимости, вы можете использовать версию LTS. Или использовать нокаут. Тогда вы можете поддержать несколько сотен человек, которые все еще используют не обновленную Windows XP с IE6 ^^

Совместимость четко указана в разделе «компромиссы» в исходном посте, поэтому идеальная поддержка старых браузеров уже является второстепенной задачей.

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

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

Будет ли это хорошей возможностью решить #6410? Это похоже на предлагаемые изменения onChange / onInput .

Обновление от 5 июня 2019 г.

Прошло много времени. Вот небольшое обновление о том, где мы находимся.

Мы начали работать над Fire в декабре. В https://github.com/facebook/react/pull/14382 и других темах есть некоторая незавершенная работа. Однако, когда мы начали удалять части системы событий, которые мы считали ненужными или устаревшими, мы обнаружили много пограничных случаев, когда это было очень полезно и предотвращало ошибки — даже в современных браузерах. Мы по-прежнему хотим сократить устаревшее раздувание, но не ясно, является ли приближение к необработанным событиям DOM лучшим направлением на практике. Сокращение кода библиотеки только для повторного добавления его в код приложения несколько раз — не лучший компромисс. И даже на уровне приложения это не всегда возможно исправить.

Отдельно, работая над FB5 , мы поняли, что даже при использовании React сегодня есть существенные трудности в реализации пользовательских интерфейсов, которые прекрасно работают и чувствуют себя как на мышиных, так и на сенсорных устройствах. Даже такие базовые вещи, как кнопки, ощущаются совершенно по-разному при использовании мыши и касания, когда вы используете такие события, как onClick , и становится еще сложнее добиться согласованного поведения при наведении курсора, фокусе и т. д.

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

В результате этого расследования мы временно приостановили работу над другими элементами, которые являются частью React Fire, и решили сначала сосредоточиться только на системе событий. Этот проект стал известен как React Flare (https://github.com/facebook/react/issues/15257). Это достаточно сложно само по себе и влияет на другие элементы в этом списке, поэтому мы сначала сосредоточимся на нем отдельно.

Цель React Flare — упростить создание пользовательских интерфейсов, которые отлично работают на настольных и мобильных устройствах, с помощью мыши и касания и которые доступны. Он включает в себя декларативные API для управления такими взаимодействиями, как нажатие, наведение и фокусировка. В отличие от текущей системы событий React, дизайн Flare не раздувает пакет событий, которые вы не используете, и должен позволить сократить объем кода в библиотеках пользовательского интерфейса, которые имеют дело с событиями мыши и касания.

React Flare все еще является экспериментом, но мы достаточно уверены в его общем направлении и планируем в конечном итоге сделать его официально доступным с открытым исходным кодом. (На данный момент это работает только в том случае, если вы вручную собираете из мастера, и нет никаких гарантий semver, поскольку мы активно работаем над этим.) правильное наименование, документация и т. д. Может быть, react/events или что-то в этом роде. Со временем мы хотели бы предложить аналогичные события и в React Native.

После того, как мы закончим первоначальную реализацию React Flare, мы вернемся к списку React Fire и переоценим все остальные пункты, используя то, что мы из него узнали. Все еще вероятно, что если Flare возьмет на себя «более богатый» набор событий, мы сможем упростить «базовую» обработку событий в React DOM и убрать кучу полифилов. Спасибо всем за обсуждение до сих пор, и я надеюсь, что это полезно.

Отличная работа! Таким образом, система событий по-прежнему необходима для балансировки событий мыши и касания, но она будет легкой и независимой от React.

Будет ли «React Flare» входить в состав пакета React по умолчанию или потребуется дополнительная установка, учитывая количество API, с которым он будет поставляться?

Мы хотели бы избежать объединения неиспользуемого кода. Таким образом, текущее намерение состоит в том, чтобы подписаться на API. Возможно отдельные точки входа в одном пакете.

Будет ли эта система событий мыши и касания использовать PointerEvent ? Я не видел упоминания об этом веб-стандарте в предыдущем обновлении, поэтому просто хотел довести его до вашего сведения.

События указателя — это события DOM, которые запускаются для указывающего устройства. Они предназначены для создания единой модели событий DOM для обработки указывающих устройств ввода, таких как мышь, перо/стилус или касание (например, один или несколько пальцев). Указатель — это аппаратно-независимое устройство, которое может ориентироваться на определенный набор экранных координат. Наличие единой модели событий для указателей может упростить создание веб-сайтов и приложений и обеспечить удобство работы независимо от аппаратного обеспечения пользователя.

А вот и прямая ссылка на текущую совместимость браузера .

@jonathantneal Да, новая система активно использует события указателя — с откатами к событиям мыши / касания, когда нет поддержки событий указателя.

Я обеспокоен тем, что https://github.com/facebook/react/issues/11347 не был затронут в этой проблеме. React проваливается https://custom-elements-everywhere.com.

Пожалуйста, учитывайте теневой корень при изменении системы событий — простое присоединение к корню React сегодня не решит большинство проблем, только присоединение к элементу (https://github.com/facebook/react/issues/9242, https:// github.com/facebook/react/issues/15759, https://github.com/facebook/react/issues/13713, https://github.com/facebook/react/issues/11827)

В этом обновлении: https://github.com/facebook/react/issues/13525#issuecomment -499196939 @gaearon упоминает:

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

Мне было любопытно, задокументирован ли где-нибудь список этих крайних случаев?

@gaearon теперь, когда Flare вышел (SCNR), есть ли обновленный план (относительно обновления от 5 июня 2019 г. ), как действовать?

И, как и @trusktr , я также хотел бы, чтобы здесь был адресован # 11347 .

Можно разделить полифиллы на другой пакет, особенно тот, который не относится к основным вечнозеленым браузерам.

Привет всем, прошло некоторое время, и мы пробовали некоторые из этих вещей время от времени.

Позвольте мне дать обновленную информацию о каждом:

Мы все еще хотим это сделать, но мы решили «зарезервировать» React 17, чтобы иметь минимально возможные критические изменения , чтобы он мог сосредоточиться на следующем элементе в этом списке. Так что это изменение подождет до React 18.

  • Прикрепляйте события к корню React, а не к документу (https://github.com/facebook/react/issues/2043). Присоединение обработчиков событий к документу становится проблемой при встраивании приложений React в более крупные системы. Редактор Atom был одним из первых, кто столкнулся с этим. На любом крупном веб-сайте рано или поздно возникают очень сложные пограничные случаи, связанные с взаимодействием stopPropagation с кодом, отличным от React, или с корнями React (https://github.com/facebook/react/issues/8693, https://github). .com/facebook/react/pull/8117, https://github.com/facebook/react/issues/12518). Мы также хотим с готовностью привязывать события к каждому корню, чтобы мы могли выполнять меньше проверок во время выполнения во время обновлений.

Мы делаем это в React 17. Это оказался огромный кусок работы, но, к счастью, он завершен.

  • Перейдите с onChange на onInput и не используйте полифиллы для неконтролируемых компонентов (https://github.com/facebook/react/issues/9657). Подробный план см. в связанной проблеме. Сбивает с толку то, что React использует другое имя события для того, что известно как событие input в DOM. Хотя обычно мы избегаем таких больших изменений без существенной выгоды, в данном случае мы также хотим изменить поведение, чтобы устранить некоторую сложность, которая необходима только для крайних случаев, таких как изменение контролируемых входных данных. Поэтому имеет смысл сделать эти два изменения вместе и использовать это как возможность заставить onInput и onChange работать точно так же, как события DOM работают для неконтролируемых компонентов.

Вероятно, мы еще вернемся к этому, но пока неясно, сколько здесь стоит делать оттока. Так что это все еще TBD.

  • Кардинально упростить систему событий (https://github.com/facebook/react/issues/4751). Текущая система событий почти не изменилась с момента ее первоначальной реализации в 2013 году. Она повторно используется в React DOM и React Native, поэтому она излишне абстрактна. Многие полифилы, которые он предоставляет, не нужны современным браузерам, а некоторые из них создают больше проблем, чем решают. На него также приходится значительная часть размера пакета React DOM. У нас нет конкретного плана, но мы, вероятно, полностью разветвим систему событий, а затем посмотрим, насколько минимальной мы сможем ее сделать, если будем придерживаться того, что дает нам DOM. Вполне вероятно, что мы вообще избавимся от синтетических событий. Мы должны прекратить всплывать события, такие как медиа-события, которые не всплывают в DOM и не имеют веской причины всплывать. Мы хотим сохранить некоторые специфичные для React возможности, такие как всплывающее окно через порталы, но мы попытаемся сделать это с помощью более простых средств (например, повторной отправки события). Пассивные события, вероятно, будут частью этого.

Мы пробовали это в начале 2019 года, и действительно минимальная система событий не очень хорошо сработала в нашем внутреннем тестировании. В React было проведено довольно много межбраузерной нормализации, которая по-прежнему полезна для людей со старыми браузерами или в более нишевых областях, таких как редакторы ввода расширенного текста, использующие contentEditable . Тем не менее, в рамках нашей работы по привязке событий к корням мы убрали большую часть абстракции из системы событий, чтобы ее было легче понять и улучшить в будущем. В рамках React 17 мы удаляем «пул событий», который вызывал много путаницы, а также больше не всплываем событие onScroll . Мы, скорее всего, последуем остановке всплытия медиа-событий в React 18, приблизив поведение React к поведению браузера. Мы сэкономили несколько байтов с новой системой событий, но они были заняты новыми функциями, над которыми мы работаем, поэтому это не приведет к общему уменьшению размера пакета.

  • classNameclass (https://github.com/facebook/react/issues/4331, см. также https://github.com/facebook/react/issues/13525#issuecomment- 417818906 ниже). Это предлагалось бесчисленное количество раз. Мы уже разрешаем передачу class вниз узлу DOM в React 16. Путаница, которую это создает, не стоит синтаксических ограничений, от которых он пытается защититься. Мы бы не стали делать это изменение само по себе, но в сочетании со всем остальным, что выше, оно имеет смысл. Обратите внимание, что мы не можем просто разрешить и то, и другое без предупреждений, потому что это очень затрудняет обработку компонентной экосистемы. Каждый компонент должен научиться правильно обрабатывать оба компонента, и существует риск их конфликта. Поскольку многие компоненты обрабатывают className (например, добавляя к нему), это слишком подвержено ошибкам.

Это была самая спорная часть предложения. С тех пор мы выпустили хуки, которые поощряют написание функциональных компонентов. В функциональных компонентах мы обычно предлагаем использовать деструктурирование для свойств, но вы не можете написать { class, ... } , потому что это будет синтаксической ошибкой. Так что в целом не ясно, достаточно ли это эргономично, чтобы на самом деле довести дело до конца. Я думаю, вполне вероятно, что мы вернемся к этому в будущем или, по крайней мере, сделаем так, чтобы class не предупреждали и позволяли людям делать то, что они хотят. Но пока отложим эту идею.

Привет, это отличная статья!
Просто хотел узнать, есть ли какой-либо план по уменьшению размера продукта React-DOM? Для мобильных приложений это по-прежнему накладные расходы, поскольку браузер будет анализировать более 100 КБ React-DOM JS, а затем другие модули. Затем специфичный для приложения JS.
Для страниц с богатым содержанием это приводит к большей блокировке и большему TTI.

Любая идея, когда мы сможем увидеть такие изменения?

@morevolk-latei По вашим измерениям, сколько времени тратится на синтаксический анализ 100 КБ ReactDOM?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги