Как стать автором
Обновить

Комментарии 13

Я так и не понял, что поменялось в "решении 1" )) Функция как создавалась на лету, так и создается. Про useCallback ни слова..


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

Да, в функциональных компонентах нужен useCallback, в оригинале классовый метод создаётся при инициализации, только не ясно как в ФК это поможет уменьшить память, скорее наоборот должно увеличить, скорость перерендера — возможно и то нужно смотреть на реальные примеры

в оригинале нет ни какой логики onClose, это зачем-то добавил автор перевода

Зря вы это перевели. Статья очень низкого качества. Пункт 1 так вообще полная чушь. Пункт 4 не про "await" а про запуск в параллели, вместо последовательности (await там остался). Пункт 2 смешной… Они и правда использовали JSON.stringify(prevProps.data) !== JSON.stringify(this.props.data)? Ух… Не удивительно что они ускорили проект. После такого то.


В общем статья какой-то мусор (я про оригинал).

Да и ретурнуть null лучше не перед jsx, а в месте вызова самого компонента
{isOpen && <MyModal>}
  1. Некорректный пример (как написали выше). Самый крутой способ это когда можно вынести функцию из компонента, но доступен далеко не всегда. Дальше начинается вопрос с useCallback и тут очень все непросто, покуда сам useCallbakc не бесплатен и вопрос что дешевле: перерисовать компонент или прибегнуть к хукам совсем не прост.

  2. Спасибо, капитан, мы учтём что нудно каждый раз думать обновление каких данных должно приводить к перерисовки. Впрочем, это отличный способ заняться преждевременной оптимизацией: при изменении бизнес требований часто нужны другие части для обновления. А Json stringify это победа. Гораздо лучше заранее правильно проектировать данные, все эти deep compare абсолютно всегда стрельба себе в ногу без исключений.

  3. Прощайте анимашки, хех. Это я к тому что обычно библиотеки требуют такой апи (привет antd) не просто так, в противном случае это копитанство.

  4. великолепный перевод, в котором полностью потерян смысл. На первый взгляд появляется ощущение что async await накладывает дополнительные расходы (что оно делает, но это экономия на спичках. Да даже не спичках, а что еще дешевле?), но по тексту просто рекомендация грузить данные параллельно. Это, кончено, хорошо, но не всегда просто или вообще возможно, а ещё очередное капитанство и вообще не имеет отношения к реакту, а скорее про js или вообще про программирование как таковое.

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

3. Прощайте анимашки, хех. Это я к тому что обычно библиотеки требуют такой апи (привет antd) не просто так

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

Почему это плохая идея?

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

хм, было бы здорово если бы в браузере была какая-то апишка типа «сделать скриншот дивчика и показывать его пока идёт анимашка», но вот нет.

хм, было бы здорово если бы в браузере была какая-то апишка типа «сделать скриншот дивчика и показывать его пока идёт анимашка», но вот нет.

Я в порядке бреда как-то что-то подобное реализовал. Алгоритм был примерно такой:


  • render запоминаем innerHTML как строку
  • на unmount восстанавливаем вручную
  • запускаем нужные анимации
  • по окончанию анимации убиваем

Получилось неплохо. Использовал в диалогах. Понятное дело что этот HTML макет после innerHTML = savedHTML был не интерактивным. Ну и понятно, что не все возможные случаи это покрывает. Но получилось довольно дёшево и сердито. Пожалуй стоит поиграться с этой идеей ещё разок. Главное преимущество получалось в том, что из-за анимации закрытия не приходилось усложнять никак с этим не связанный код.

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

Про cloneNode я тоже думал, но, кажется, ЕМНИП, проблема была в том, что его пришлось бы вызывать при каждом рендере превентивно. Точной причины почему уже не помню, кажется что-то связанно с тем что на момент unmount-а клонировать уже поздно, т.к. HTML уже не тот. Видимо какие-то контексты и условный рендеринг мешали.

Предположим, что мы повторно обращаемся к API и получаем те же данные. Должны ли мы в этом случае обновлять хранилище? Короткий ответ — нет. Если мы это сделаем, то компоненты, использующие такие данные будут повторно отрисованы, поскольку изменилась ссылка на данные.

Ну вот начать использовать Reselect, к примеру, и тогда «компоненты, использующие такие данные» не будут повторно отрисованы. При этом не понадобятся костыли в виде сравнения состояния после получения данных и перед добавлением в хранилище.

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

Не стоило. Вообще. Совсем

Зарегистрируйтесь на Хабре, чтобы оставить комментарий