Single Source of Truth это про store. Store должен быть единственным верным источником данных и ничто иное (за исключением локальных данных компонентов, как верно подметили в соседней ветке о формах).
Например у меня в проекте есть action `searchAll({ searchText })`, на который реагирует saga для запуска запроса, сбрасываются фильтры, устанавливаются правильные флажки для отображения доступных фильтров. В целом, можно было обойтись одной ветвью стейта и редьюсером (что я, наверное, и сделал бы), но я попал на проект, где вместо одного searchAll диспатчился десяток разнородных action, что тригерило лишние вызовы хуков, редьюсеров и так далее.
К сожалению, всё не так. Идеология redux прямо предполагает, что на один action реагируют много reducer и соответствующим образом меняют только ту ветвь состояния, за которую эти reducer отвечают.
Весьма субъективно. Порой, чтобы вынести подобные конструкции в отдельный компонент, требуется на порядок больше кода, чем просто заинлайнить (вы же используете TypeScript или PropTypes?).
Почему бы не сделать так
К части «или так»: лучше, но вы потеряли объект item.
А именно не использовать анонимную функцию для рендеринга внутри .map.
Это важно при передаче функций в props, поскольку тогда (если компонент мемоизирован стандартными средствами) каждый ре-рендер будет новая ссылка на функцию. В контексте Array.prototype.map это не имеет инкакого значения.
И последний шаг который мы можем сделать это использовать так называемый PureComponent для рендеринга каждого item
Спорно. Порой это только повышает расход ресурсов (процессор и память), а порой лучше мемоизировать компонент, который рендерит сам список.
И пожалуйста не используйте для этого index элемента в массиве. Ниже я расскажу почему.
И не рассказали. Нельзя так с читателем.
Для страждущих: key нужен Реакту для того, чтобы корректно запускать методы жизненного цикла для появляющихся и исчезающих из списка компонентов.
Это, конечно, лучше, чем обычная лапша, где об оптимизации даже не задумывались, но всё жи слишком много безаппеляционных утверждений.
Ранее был яростным поклонником систем на базе Linux (начинал, не поверите, с Gentoo в далёком 2007) и моя дружба с линуксами продолжалась более десяти лет. На работе сейчас использую MBP 15" (до этого был MBP 13") и пребываю в восторге.
1) Я точно так же долгое время не понимал, зачем нужны ноуты, ведь десктоп это так классно. Сейчас мне наоборот сложно воспринимать десктоп, он же большой, зачастую шумный, и не мобильный. Тут большую роль играет дело привычки. А чтобы не сидеть сгорбившись, можно отрегулировать высоту стола или таки подключить внешние устройства.
2) На самом деле это тачпад. Трекпад это немного о другом. Вся мощь тачпада в MBP, помимо того, что он, вероятно, один из лучших на рынке, это взаимодействие с операционной системой. Переключение между рабочими столами это кусочек магии, не надо сидель альт-табаться или тянуться к мышке. Навигация в браузере налогично. Очень много разных жестов, которые упрощают и ускоряют взаимодействие с системой. Просто попробуйте открыть IDE на отдельном рабочем столе и попереключаться тачпадом, проводя тремя пальцами в стороны. Более того, каждый монитор может иметь свой набор рабочих столов. Магия! :)
3) Просто вы привыкли к другой системе горячих клавиш. Если у вас есть несколько открытых окон одного приложения — используйте Command + `, что ещё быстрее. Я похожим приёмом пользовался ещё в те времена, когда работал на других Юникс-подобных системах.
4) Тут особенности восприятия, с этим ничего не поделать.
5) Другие комбинации клавиш это нормально. Я жутко привык к отдельным Command, Control и Option, и когда мне нужно работать с Windows — ощущаю, что на MBP эргономика реально удобнее. Особенно чувствуется в терминале, когда Command + C это однозначно копировать текст, а Control + C это однозначно убить процесс, без использования дополнительных модификаторов.
6) Как человек, начинавший с Gentoo, где собирал ядро самостоятельно (без использования genkernel, только make menuconfig) — я абсолютно счастлив, что сейчас мне не надо тратить уйму времени на доведение системы до вменяемого состояния.
А уж если выйти за рамки MacOS и поговорить об интеграции экосистемы, в частности, MacOS + iPhone, то, ух! Можно звонить и отвечать на звонки без поисков телефона! :)
> таблица транзакций слева в 100 000 записей под гиг, которую хочет быстро проскролить аудитор
Если честно, не уверен, что это получится быстро даже на голом DOM. Обычно, когда работают с настолько большими датасетами, используют виртуализацию (react-virtualized, react-window).
> Т.е. памяти страница отожрет в 2 раза больше как минимум
Отожрёт если с прозрачностью ссылок что-то пойдёт не так, и только на отображаемую сущность.
> Еще наверняка есть какие-то обертки для каждой строки, которые слушают изменения в сторе
Нету. Стор модифицируется запуском редьюсера в ответ на action, который прокинули в систему (да, тут нюанс — запустятся все редьюсеры, если говорить о классических редьюсерах на switch/case). Дальше работает shallow comparison (проверяется ссылочная эквивалентность данных), чтобы избежать лишних ре-рендеров.
> Плюс журналируются изменные стэйты
Журналируются только action (обычный JS объект со строковым свойством type и вашей информацией), и только когда был подключён Redux Dev Tools или схожий middleware.
UPD: redux, кстати, только хранит данные, а уж как их отображать — не его задача. Вы можете работать хоть с VanillaJS и использовать redux, главное — подписаться на стор и адекватно реагировать на его изменения.
Сейчас по долгу службы приходится писать на ReactNative с парочкой нативных модулей и хотел бы узнать, возможно ли использовать один экземпляр IDE для разработки, запуска и дебага (нативного и скриптового) приложения?
Из того, что мне удалось потестить, WebStorm отлично справляется со скриптовый частью проекта (ещё бы не справлялся, там же обычный React), а AppCode — с нативной.
На самом деле, Flutter использует, если не подводит память, Skia, и все виджеты в нём рисуются этим движком. Тут Kivy концептуально не отличается. А вот ReactNative — напротив, работает с нативным компонентами, но имеет потери производительности из-за наличия Js <> Native бриджа.
> увидев 10 часов в неделю, потраченных на тестирование, руководитель не обрадуется
И, я думаю, будет прав. Написание юнит-тестов должно быть включено в эстимейт. У меня на практике получается, что при TDD вместо ручного тестирования после каждой итерации, время на разработку уходит такое же или лишь немногим больше, чем без тестов. Естественно, стараюсь покрывать happy path и ожидаемые ошибки.
Что в очередной раз доказывает, что меньшее количество точек с запятой не являются гарантией меньшего количества багов.
На самом деле, есть и неплохие (но неполные) упражнения (в частности, игры со счётчиками и setTimeout, которые показывают понимание Event Loop и области видимости), но мне откровенно жаль, что 30+ человек попали к некомпетентному интервьюверу и я не понимаю, как крупная продуктовая компания могла такое допустить.
Какой кошмар. Спасибо, что пролили свет на интервью в Яндексе.
В частности, за решение задач «в духе Яндекса». Люблю и уважаю ФП, но однобуквенные переменные, тернарка в тернарке это за гранью. Можно ведь сделать проще.
К тому же, используется Array.prototype.unshift, что, как бы, «неправославно» в рамках функциональной парадигмы, которой вы пытаетесь следовать.
Ваше решение с промисами (там, где gif), так же под вопросом. Во первых, переменная user там не нужна. category можно оставить как шорткат к data.category. Первые два запроса можно выполнить паралельно, что уменьшит время ответа.
Суть не в этом. У нас на мобилке помещается, условно, 50 символов, на десктопе — 200. При этом, разные телефоны будут вмещать разное количество символов в строке, а десктопные клиенты зависят от ширины окна. И нам никак не угадать, сколько символов будут комфортными для чтения. Особенно с учётом того, что один и тот же аккаунт может быть запущен и на десктопе, и на телефоне, и на планшете. А везде установлен разные шрифты и разные размеры шрифтов, так что всё становится ещё веселее :)
Проблема в том, что с точками не угадать, сколько их нужно поставить, потому что сам Telegram работает и на десктопе, и на мобилках, и в вебе. Я для своего бота пришёл к отображению денег в начале строки, моноширным шрифтом с выравниванием по правому краю с использованием пробелов.
Например у меня в проекте есть action `searchAll({ searchText })`, на который реагирует saga для запуска запроса, сбрасываются фильтры, устанавливаются правильные флажки для отображения доступных фильтров. В целом, можно было обойтись одной ветвью стейта и редьюсером (что я, наверное, и сделал бы), но я попал на проект, где вместо одного searchAll диспатчился десяток разнородных action, что тригерило лишние вызовы хуков, редьюсеров и так далее.
redux.js.org/faq/actions#is-there-always-a-one-to-one-mapping-between-reducers-and-actions
Весьма субъективно. Порой, чтобы вынести подобные конструкции в отдельный компонент, требуется на порядок больше кода, чем просто заинлайнить (вы же используете TypeScript или PropTypes?).
К части «или так»: лучше, но вы потеряли объект item.
Это важно при передаче функций в props, поскольку тогда (если компонент мемоизирован стандартными средствами) каждый ре-рендер будет новая ссылка на функцию. В контексте Array.prototype.map это не имеет инкакого значения.
Спорно. Порой это только повышает расход ресурсов (процессор и память), а порой лучше мемоизировать компонент, который рендерит сам список.
И не рассказали. Нельзя так с читателем.
Для страждущих: key нужен Реакту для того, чтобы корректно запускать методы жизненного цикла для появляющихся и исчезающих из списка компонентов.
Это, конечно, лучше, чем обычная лапша, где об оптимизации даже не задумывались, но всё жи слишком много безаппеляционных утверждений.
1) Я точно так же долгое время не понимал, зачем нужны ноуты, ведь десктоп это так классно. Сейчас мне наоборот сложно воспринимать десктоп, он же большой, зачастую шумный, и не мобильный. Тут большую роль играет дело привычки. А чтобы не сидеть сгорбившись, можно отрегулировать высоту стола или таки подключить внешние устройства.
2) На самом деле это тачпад. Трекпад это немного о другом. Вся мощь тачпада в MBP, помимо того, что он, вероятно, один из лучших на рынке, это взаимодействие с операционной системой. Переключение между рабочими столами это кусочек магии, не надо сидель альт-табаться или тянуться к мышке. Навигация в браузере налогично. Очень много разных жестов, которые упрощают и ускоряют взаимодействие с системой. Просто попробуйте открыть IDE на отдельном рабочем столе и попереключаться тачпадом, проводя тремя пальцами в стороны. Более того, каждый монитор может иметь свой набор рабочих столов. Магия! :)
3) Просто вы привыкли к другой системе горячих клавиш. Если у вас есть несколько открытых окон одного приложения — используйте Command + `, что ещё быстрее. Я похожим приёмом пользовался ещё в те времена, когда работал на других Юникс-подобных системах.
4) Тут особенности восприятия, с этим ничего не поделать.
5) Другие комбинации клавиш это нормально. Я жутко привык к отдельным Command, Control и Option, и когда мне нужно работать с Windows — ощущаю, что на MBP эргономика реально удобнее. Особенно чувствуется в терминале, когда Command + C это однозначно копировать текст, а Control + C это однозначно убить процесс, без использования дополнительных модификаторов.
6) Как человек, начинавший с Gentoo, где собирал ядро самостоятельно (без использования genkernel, только make menuconfig) — я абсолютно счастлив, что сейчас мне не надо тратить уйму времени на доведение системы до вменяемого состояния.
А уж если выйти за рамки MacOS и поговорить об интеграции экосистемы, в частности, MacOS + iPhone, то, ух! Можно звонить и отвечать на звонки без поисков телефона! :)
Если честно, не уверен, что это получится быстро даже на голом DOM. Обычно, когда работают с настолько большими датасетами, используют виртуализацию (react-virtualized, react-window).
> Т.е. памяти страница отожрет в 2 раза больше как минимум
Отожрёт если с прозрачностью ссылок что-то пойдёт не так, и только на отображаемую сущность.
> Еще наверняка есть какие-то обертки для каждой строки, которые слушают изменения в сторе
Нету. Стор модифицируется запуском редьюсера в ответ на action, который прокинули в систему (да, тут нюанс — запустятся все редьюсеры, если говорить о классических редьюсерах на switch/case). Дальше работает shallow comparison (проверяется ссылочная эквивалентность данных), чтобы избежать лишних ре-рендеров.
> Плюс журналируются изменные стэйты
Журналируются только action (обычный JS объект со строковым свойством type и вашей информацией), и только когда был подключён Redux Dev Tools или схожий middleware.
UPD: redux, кстати, только хранит данные, а уж как их отображать — не его задача. Вы можете работать хоть с VanillaJS и использовать redux, главное — подписаться на стор и адекватно реагировать на его изменения.
Из того, что мне удалось потестить, WebStorm отлично справляется со скриптовый частью проекта (ещё бы не справлялся, там же обычный React), а AppCode — с нативной.
На самом деле, Flutter использует, если не подводит память, Skia, и все виджеты в нём рисуются этим движком. Тут Kivy концептуально не отличается. А вот ReactNative — напротив, работает с нативным компонентами, но имеет потери производительности из-за наличия Js <> Native бриджа.
$8.9 в месяц или $89 в первый год (дальше — меньше, вплоть до $53) это не много для превосходного инструмента.
Потому что надо юзать
jest.spyOn(global, 'fetch').mockResolvedValue(...)
:)И, я думаю, будет прав. Написание юнит-тестов должно быть включено в эстимейт. У меня на практике получается, что при TDD вместо ручного тестирования после каждой итерации, время на разработку уходит такое же или лишь немногим больше, чем без тестов. Естественно, стараюсь покрывать happy path и ожидаемые ошибки.
getRanges([1,2,3,6]) => "1-3,6-6"
Что в очередной раз доказывает, что меньшее количество точек с запятой не являются гарантией меньшего количества багов.
На самом деле, есть и неплохие (но неполные) упражнения (в частности, игры со счётчиками и setTimeout, которые показывают понимание Event Loop и области видимости), но мне откровенно жаль, что 30+ человек попали к некомпетентному интервьюверу и я не понимаю, как крупная продуктовая компания могла такое допустить.
В частности, за решение задач «в духе Яндекса». Люблю и уважаю ФП, но однобуквенные переменные, тернарка в тернарке это за гранью. Можно ведь сделать проще.
К тому же, используется
Array.prototype.unshift
, что, как бы, «неправославно» в рамках функциональной парадигмы, которой вы пытаетесь следовать.Ваше решение с промисами (там, где gif), так же под вопросом. Во первых, переменная
user
там не нужна.category
можно оставить как шорткат кdata.category
. Первые два запроса можно выполнить паралельно, что уменьшит время ответа.Да, только вот по вашей ссылке первое же предложение это
> While trying out the experimental hashmap raw entry API
Что как бы подразумевает, что что-то может пойти не так. К тому же, этот API нужно ещё и активировать, указав
#![feature(hash_raw_entry)]
:)
Я его внедрял на одном из проектов вместе с husky, зашло очень даже хорошо.
Ну так не ловите исключение в вашей функции или пробрасывайте наверх после выполнения необходимых действий в catch.
К слову, в вашей «исправлённой» функции всё так же присутствует баг, с которым вы пытались бороться.