artalog
🛑 в этом посте есть ошибки 🛑 Идемпотентность. TLDR: не мутируйте в useEffect! 1. Реакт позволяет с помощью useEffect описать какой-то эффект в ответ на изменение данных. 2. В рамках конкурентного рендеринга эффекты могут перевызываться лишний раз, под StrictMod…
Я был сильно не прав, useEffect не вызывается лишний раз.
Очень стыдно, простите 🙃
Избыточно перевызываться могут только хуки мемоизации.
За поправку спасибо @BuggyTheClown.
Но я еще подкину интересного по теме: Design decision: why do we need the stale closure problem in the first place? Старый и до сих пор не закрытый ишьес, в котором можно найти много занятный примеров. Может, повычитываю его потом повнимательней и скину сюда самое интересное.
UPD: useEffect без зависимостей все же может вызываться дважды в девелопе со стрикт модом.
Очень стыдно, простите 🙃
Избыточно перевызываться могут только хуки мемоизации.
За поправку спасибо @BuggyTheClown.
Но я еще подкину интересного по теме: Design decision: why do we need the stale closure problem in the first place? Старый и до сих пор не закрытый ишьес, в котором можно найти много занятный примеров. Может, повычитываю его потом повнимательней и скину сюда самое интересное.
UPD: useEffect без зависимостей все же может вызываться дважды в девелопе со стрикт модом.
GitHub
Design decision: why do we need the stale closure problem in the first place? · Issue #16956 · facebook/react
Hi, I initially asked this on Twitter and @gaearon suggested me to open an issue instead. The original thread is here: https://twitter.com/sebastienlorber/status/1178328607376232449?s=19 More easy ...
👍4🤔2🔥1
Resumability: a no-overhead alternative to hydration
Статья подчеркивает то о чем я говорю уже года два и размышляю над возможной реализацией для реатома. Сама идея проста и состоит из двух частей: давайте грузить на клиент джаваскрипт только для интерактивности (без темплейтов) и делать это лениво.
Напомню проблему: всякие реакты и даже свелт после загрузки HTML от SSG / SSR предполагают загрузку его копии внутри JS в виде шаблонов, для построение биндингов к дому. Выглядит очень избыточно и статья о том и говорит. А еще это способствует не гранулярной работе с ДОМом и последующим томозам в рантайме.
Проблема делать иначе в том что для построения биндингов ЖСа к событиям и атрибутам ДОМа без наличия всего тела темплейта нужен достаточно хитрый компайлер, который все равно будет вас сильно ограничивать.
Но это в случае если хочется оставить возможность писать обработку данных прямо в темплейте. А если выносить ее в отдельное место и в JSX описывать только ссылки на реактивные сущности, то компилятор можно значительно упростить, а разработчика заставить описывать всю обработку состояния в соответствующем месте, за что я всегда выступал.
Уточню, что упрощение компилятора нужно не что бы ментейнеров библиотеки разгрузить, а что бы сделать инструмент с меньшей сложностью, большей предсказуемостью и простотой дебага.
Будет чудо, если в этом году я найду время на то что бы этим заняться 👀
Статья подчеркивает то о чем я говорю уже года два и размышляю над возможной реализацией для реатома. Сама идея проста и состоит из двух частей: давайте грузить на клиент джаваскрипт только для интерактивности (без темплейтов) и делать это лениво.
Напомню проблему: всякие реакты и даже свелт после загрузки HTML от SSG / SSR предполагают загрузку его копии внутри JS в виде шаблонов, для построение биндингов к дому. Выглядит очень избыточно и статья о том и говорит. А еще это способствует не гранулярной работе с ДОМом и последующим томозам в рантайме.
Проблема делать иначе в том что для построения биндингов ЖСа к событиям и атрибутам ДОМа без наличия всего тела темплейта нужен достаточно хитрый компайлер, который все равно будет вас сильно ограничивать.
Но это в случае если хочется оставить возможность писать обработку данных прямо в темплейте. А если выносить ее в отдельное место и в JSX описывать только ссылки на реактивные сущности, то компилятор можно значительно упростить, а разработчика заставить описывать всю обработку состояния в соответствующем месте, за что я всегда выступал.
Уточню, что упрощение компилятора нужно не что бы ментейнеров библиотеки разгрузить, а что бы сделать инструмент с меньшей сложностью, большей предсказуемостью и простотой дебага.
Будет чудо, если в этом году я найду время на то что бы этим заняться 👀
DEV Community
Hydration is Pure Overhead
Why hydration is a workaround, not the solution.
👍12
rome.tools
Идея унифицированного инструмента для всех AOT (билд-тайм) преобразований очень здравая, зачем парсить текст и выделять семантику несколько раз. За Ромом стоят опытные разработчики (автор Babel), они уже подняли инвестиции и все бы ничего… Но продукта небыло очень долго и лично меня это сильно смущает. Говорят много, пощупать можно было мало. Два года потребовалось что бы выпустить форматтер, о котором я сегодня и хотел рассказать.
Начал понемногу пробовать его через расширение для vscode на реатоме, скорее по фану, пока что. Но оно preview, не отрабатывает и не пишет ошибки в output, если таковые есть - просто ничего не происходит. В плейграунде можно увидеть ошибки, но я вот вставил туда 600 строк кода и интерфейс фризится на секунды на моем m1.
Разницу с prettier можно увидеть тут. Правда, туда залетели дефолтные табы, использование которых странно для тех кто близок к OSS и гитхабу и знает как ужасно они там отображаются.
В общем, как вы могли заметить, у меня впечатления от всей этой истории негативные. Но, честно говоря, это потому что я многого ожидаю от этой тулзовины и хочется получить сразу все здесь и сейчас. Надеюсь, у них все получится.
Идея унифицированного инструмента для всех AOT (билд-тайм) преобразований очень здравая, зачем парсить текст и выделять семантику несколько раз. За Ромом стоят опытные разработчики (автор Babel), они уже подняли инвестиции и все бы ничего… Но продукта небыло очень долго и лично меня это сильно смущает. Говорят много, пощупать можно было мало. Два года потребовалось что бы выпустить форматтер, о котором я сегодня и хотел рассказать.
Начал понемногу пробовать его через расширение для vscode на реатоме, скорее по фану, пока что. Но оно preview, не отрабатывает и не пишет ошибки в output, если таковые есть - просто ничего не происходит. В плейграунде можно увидеть ошибки, но я вот вставил туда 600 строк кода и интерфейс фризится на секунды на моем m1.
Разницу с prettier можно увидеть тут. Правда, туда залетели дефолтные табы, использование которых странно для тех кто близок к OSS и гитхабу и знает как ужасно они там отображаются.
В общем, как вы могли заметить, у меня впечатления от всей этой истории негативные. Но, честно говоря, это потому что я многого ожидаю от этой тулзовины и хочется получить сразу все здесь и сейчас. Надеюсь, у них все получится.
rome.tools
Announcing Rome Formatter
Release of Rome Formatter, a super fast formatter for JavaScript and TypeScript
👍5🤔2
Вот несколько примеров отличия от prettier, которые не касаются конфигурационных параметров.
🔥3🤔1
Так, пояснение. Я не верю в единственный правильный форматтер и только ради условно красившего форматирования уходить с преттиера, который стандарт индустрии, не стал бы.
У рома главная фича в экосистеме, которой сейчас нет 🙃.
Но! У него есть возможность парсить даже синтаксически ошибочный код - это может быть полезным во время разработки.
У рома главная фича в экосистеме, которой сейчас нет 🙃.
Но! У него есть возможность парсить даже синтаксически ошибочный код - это может быть полезным во время разработки.
👍5
Асинхронная очередь.
В одном чатике задали простую, но интересную задачку: нужна очередь с колбеками, которые могут быть синхронными или асинхронными и должны исполняться строго один после завершения другого. Проблема в том что в очередь новые колбеки могут прилетать асинхронно в любое время.
Ну я накидал какой-то вариант, а потом еще несколько раз доправлял какие-то баги, которые всплыли в моей голове. И не уверен что все моменты учел. Нужно обрабатывать состояние пустой очереди, поступление колбека в момент когда очередь уже пуста, но последний колбек еще выполняется (промис) и тп.
Мне показалась моя же реализация сложной и не очевидной / не надежной и я решил еще подумать. После пары экспериментов в голову стукнуло максимально простое и понятное решение:
Тут здорово что then не хранит ссылку на предыдущий промис и нам не нужно заботиться об очистке памяти, под капотом список выглядит как односвязный linked list, голову которого подчищает GC, а мы храним только хвост.
В одном чатике задали простую, но интересную задачку: нужна очередь с колбеками, которые могут быть синхронными или асинхронными и должны исполняться строго один после завершения другого. Проблема в том что в очередь новые колбеки могут прилетать асинхронно в любое время.
Ну я накидал какой-то вариант, а потом еще несколько раз доправлял какие-то баги, которые всплыли в моей голове. И не уверен что все моменты учел. Нужно обрабатывать состояние пустой очереди, поступление колбека в момент когда очередь уже пуста, но последний колбек еще выполняется (промис) и тп.
Мне показалась моя же реализация сложной и не очевидной / не надежной и я решил еще подумать. После пары экспериментов в голову стукнуло максимально простое и понятное решение:
let chain = Promise.resolve()
export const add = cb => chain = chain.then(cb)
Тут здорово что then не хранит ссылку на предыдущий промис и нам не нужно заботиться об очистке памяти, под капотом список выглядит как односвязный linked list, голову которого подчищает GC, а мы храним только хвост.
👍16🔥4
Вот еще одна простая, но очень полезная утилита для очередей.
При рассылке ботом телеграма сообщений нельзя отправлять больше 30 в секунду, иначе можно словить временную блокировку.
Заводить под это дело очередь и кидать в нее колбеки не удобно, код перестает выглядить синхронно и могут появляться конфликты имен переменных в скоупах колбека и кода после него.
Сделал утилиту с состоянием последнего времени запроса, для использования нужно авейтнуть ее вызов перед отправкой сообщения, просто и удобно.
…
Посмотрел на предыдущий пост, можно было бы сделать еще проще:
😀
При рассылке ботом телеграма сообщений нельзя отправлять больше 30 в секунду, иначе можно словить временную блокировку.
Заводить под это дело очередь и кидать в нее колбеки не удобно, код перестает выглядить синхронно и могут появляться конфликты имен переменных в скоупах колбека и кода после него.
Сделал утилиту с состоянием последнего времени запроса, для использования нужно авейтнуть ее вызов перед отправкой сообщения, просто и удобно.
…
Посмотрел на предыдущий пост, можно было бы сделать еще проще:
freeMsgLimit = () => add(sleep(TLG_MESSAGE_LIMIT))
😀
👍6
Дождаться завершения всех промисов.
Продолжаем про асинхронные очереди 🙂
Популярная задача - дождаться завершения всех асинхронных функций, даже тех что были вызваны во время этого самого ожидания. Нужно, например, что бы на сервере после диспатча в редакс получить финальный стейт для отправки на клиент.
Придумали?
Т.к. в редаксе есть единая централизованная точка входа на все IO сделать там это очень просто: накинуть мидлвару, которая создаётся из функции которая принимает колбек и создаёт в замыкании каунтер эффектов. Если из диспатча возвращается instanceOf Promise - инкрементим каунтер и вешаем finally с колбеком на декремент каунтера, где еще проверяем, если каунтер стал нулем - вызываем колбек окончания всех эффектов.
Для реатома я делал что-то похожее.
И эффектор за кажущейся простой так же требует централизованную точку входа (scope, fork) и под капотом ведёт такой же каунтер.
Продолжаем про асинхронные очереди 🙂
Популярная задача - дождаться завершения всех асинхронных функций, даже тех что были вызваны во время этого самого ожидания. Нужно, например, что бы на сервере после диспатча в редакс получить финальный стейт для отправки на клиент.
Придумали?
Т.к. в редаксе есть единая централизованная точка входа на все IO сделать там это очень просто: накинуть мидлвару, которая создаётся из функции которая принимает колбек и создаёт в замыкании каунтер эффектов. Если из диспатча возвращается instanceOf Promise - инкрементим каунтер и вешаем finally с колбеком на декремент каунтера, где еще проверяем, если каунтер стал нулем - вызываем колбек окончания всех эффектов.
store.dispatch = (…a) => {
i++
originalDispatch(…a).finaly(() => {
if (--i === 0) resolve()
})
}Для реатома я делал что-то похожее.
И эффектор за кажущейся простой так же требует централизованную точку входа (scope, fork) и под капотом ведёт такой же каунтер.
👍5
react-admin
Я искренне считаю что будущее программирования за low-code решениями.
Часто, большая половина кода - это связывание абстракций, на которые мы разделили наш код для упрощения работы с каждой составляющей домена / фреймворка / платформы. В этом не было бы необходимости, если бы используемые библиотеки сами покрывали все интеграции.
Но такие библиотеки есть, react-admin позволяет одним JSX описанием одновременно запросить, отобразить и дать изменить данные с API. Количество кода и его поддержка сокращается в разы. Квинтесенция компонентной архитектуры!
Конечно, есть миллион краевых случаев, где оно что-то не может, а где-то не интуитивно. Но со многими задачами справляется на ура. Я пробовал эту либу год назад, столкнулся с кучкой проблем, но в общем понравилось. Недавно вышла 4 версия в которой провели серьезный технический рефакторинг (redux -> react-query и mui5).
Рекомендую попробовать, хотя бы что бы посмотреть как вообще бывает.
#lowcode
Я искренне считаю что будущее программирования за low-code решениями.
Часто, большая половина кода - это связывание абстракций, на которые мы разделили наш код для упрощения работы с каждой составляющей домена / фреймворка / платформы. В этом не было бы необходимости, если бы используемые библиотеки сами покрывали все интеграции.
Но такие библиотеки есть, react-admin позволяет одним JSX описанием одновременно запросить, отобразить и дать изменить данные с API. Количество кода и его поддержка сокращается в разы. Квинтесенция компонентной архитектуры!
Конечно, есть миллион краевых случаев, где оно что-то не может, а где-то не интуитивно. Но со многими задачами справляется на ура. Я пробовал эту либу год назад, столкнулся с кучкой проблем, но в общем понравилось. Недавно вышла 4 версия в которой провели серьезный технический рефакторинг (redux -> react-query и mui5).
Рекомендую попробовать, хотя бы что бы посмотреть как вообще бывает.
#lowcode
Marmelab
React Admin
A frontend Framework for building B2B applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Material Design
👍9👎3🤔2💩2
hasura.io
Ещё одно прекрасное #lowcode решение - на стыке фреймворка и графического интерфейса.
Хасура - это платформа для быстрого построения оптимального бекенда. Основной сценарий такой: запускаем ее с кредами к одной из поддерживаемых БД, открываем сайт админки, создаем новую таблицу / колонку / связь / запись или что-то еще делаем в визуальном редакторе и мгновенно получаем обновленный GraphQL апи с типовыми CRUD операциями и базовыми констрейтами. Система пермишенов и гайды как ее настраивать есть из коробки. Для валидации и сложной / асинхронной логики есть экшены - что-то вроде встроенного serverless.
Штука которая меня особенно зацепила - это эвенты, они позволяют подписываться на изменение данных в реактивном стиле и декомпозировать связанность. Полезно в редких, но болезненных случаях, когда нужно подвязать логику к одной сущности, которая меняется во многих местах (кодовой базы), а зарефакторить одну точку входа возможности нет.
Вообще, фич у Хасуры очень много: миграции, REST апи, кеширование, оптимизации SQL и куча всего. И мне хочется похвалить их документацию, за пол года пользования у меня почти не появлялись неотвеченные вопросы.
Из проблем. Нет асинхронных транзакций. Нет возможности валидировать компьютеды в постгре. Еще была вот такая проблема, но она уже закрыта (проектом тем уже не занимаюсь, проверить не могу).
При этом, им уже лет или больше, они в опенсурсе, написано оно на хаскеле 🙃 и за все мое время пользования этот продукт воспринимался не как поломанный стартап, что сейчас стандарт, а как надежный и готовый продукт.
Ещё одно прекрасное #lowcode решение - на стыке фреймворка и графического интерфейса.
Хасура - это платформа для быстрого построения оптимального бекенда. Основной сценарий такой: запускаем ее с кредами к одной из поддерживаемых БД, открываем сайт админки, создаем новую таблицу / колонку / связь / запись или что-то еще делаем в визуальном редакторе и мгновенно получаем обновленный GraphQL апи с типовыми CRUD операциями и базовыми констрейтами. Система пермишенов и гайды как ее настраивать есть из коробки. Для валидации и сложной / асинхронной логики есть экшены - что-то вроде встроенного serverless.
Штука которая меня особенно зацепила - это эвенты, они позволяют подписываться на изменение данных в реактивном стиле и декомпозировать связанность. Полезно в редких, но болезненных случаях, когда нужно подвязать логику к одной сущности, которая меняется во многих местах (кодовой базы), а зарефакторить одну точку входа возможности нет.
Вообще, фич у Хасуры очень много: миграции, REST апи, кеширование, оптимизации SQL и куча всего. И мне хочется похвалить их документацию, за пол года пользования у меня почти не появлялись неотвеченные вопросы.
Из проблем. Нет асинхронных транзакций. Нет возможности валидировать компьютеды в постгре. Еще была вот такая проблема, но она уже закрыта (проектом тем уже не занимаюсь, проверить не могу).
При этом, им уже лет или больше, они в опенсурсе, написано оно на хаскеле 🙃 и за все мое время пользования этот продукт воспринимался не как поломанный стартап, что сейчас стандарт, а как надежный и готовый продукт.
👍13