Free React For Beginners
3.46K subscribers
231 photos
5 videos
1 file
385 links
💻 Про #React та #frontend та #веб розробку
🧑‍🎓 Для початківців і не тільки

👉 https://www.youtube.com/@reactdev
Download Telegram
N*M (1/3), або дайте мені 1000 ноутбуків

Сьогодні трохи поговоримо про оптимізацію та складність алгоритму на прикладі магазину з ноутбуками.

Уявіть собі що вам прилетіла задача відобразити таблицю з ноутбуками, а бекенд вам повертає два окремі масиви - список ноутбуків та список історій цін, спрощені моделі яких виглядають ось так:

type NoteBook = {id: number};
type PriceHistory = {entityId: number};


Завдання дуже просте: відобразити ноутбуки разом з історією цін.

Ми можемо зробити це в лоб:

function getNotebooksWithPrice(
notes: NoteBook[],
prices: PriceHistory[]
) {
return notes.map((notebook) => ({
...notebook,
price: prices
.filter((x) => x.entityId === notebook.id),
}));
}


Виглядає непогано і читається досить легко. Але тут схована одна проблемка, навіть не проблема, а міна сповільненої дії.

Для того, що зібрати усі ноутбуки з цінами нам потрібно зробити наступні кроки:

1. Пройтися по всьому списку ноутбуків (зробити N операцій де N довжина масиву ноутбуків)
2. Для кожного елементу масиву пройтися по всьому списку цін (зробити M операцій для кожного з ноутбуків, де M довжина масиву цін)

Тобто, для виконання цієї красивої функції нам потрібно N*M операцій. (вітаю, ви тільки що оцінили складність алгоритму 😊, яка склала O(N*M))

З практичної точки зору це означає наступне:

Уявімо собі, що наших ноутбуків 100 штук, а історій цін хоча б втричі більше, тобто 300. Отже, нам потрібно для кожного ноутбуку (100 разів) пройтися по всій історії цін (300 разів) що в сумі дає 30_000 операцій, що може й не так і багато, але вже й не дуже мало. А, якщо ще врахувати, що #React, за своєю природою, дуже часто рендерить компоненти заново, то невдало розмістивши цей код ви будете його виконувати постійно, що, звісно ж буде впливати як на швидкодію вашого застосунку, так і на батареї телефонів наших користувачів.

Але не це наша найбільша проблема. Найбільша наша проблема полягає в тому,що ці списки мають тенденцію до зростання, а кількість їх елементів нічим не обмежена!

Сьогодні у вас в магазині 20 ноутбуків, завтра 120, після завтра 1200 (разом з тими що виведені з асортименту). І функція, яка чудово справлялася зі 120 ноутами, на 1200 почне суттєво "тормозити" ваш UI. А на 2000, коли операцій стане 2_000 * 6_000 = 12 _000_000 на кожен рендер, наша сторінка просто стане колом 😢

Як цьому запобігти?

@reactbeginners
👍17🤯6🔥32
Free React For Beginners
N*M (1/3), або дайте мені 1000 ноутбуків Сьогодні трохи поговоримо про оптимізацію та складність алгоритму на прикладі магазину з ноутбуками. Уявіть собі що вам прилетіла задача відобразити таблицю з ноутбуками, а бекенд вам повертає два окремі масиви -…
Як цьому запобігти? (2/3)

Для того щоб запобігти такій ситуації існує старий і прекрасний лайфхак - купити кращий комп'ютер - використати Map.

Тобто трансформувати масив сутностей по якому у нас ведеться пошук у словник. Для того щоб знайти елемент у масиві, в гіршому випадку потрібно прочесати весь масив (N операцйі де N довжина масиву). А для словника це умовно одна операція, тобто складність змінюється з N на 1. Що, на попередньому прикладі дає нам 2000 операцій замість 120 мільйонів. Не так і погано?

Реалізувати це дуже просто:

// Перетворимо масив цін на словник цін
// Де ключем буде id ноутбуку
const pricesMap = prices.reduce((acc, price) => {
const { entityId } = price;
acc.has(entityId)
? acc.get(entityId)?.push(price)
: acc.set(price.entityId, [price]);

return acc;
}, new Map<number, PriceHistory[]>());


В цьому коді ми проходимо по усім цінам і створюємо на їх основі словник. Все що нам залишається це звернутися до цього словника під час формування моделі ноутбуку:

return notes.map((notebook) => ({
...notebook,
prices: pricesMap.get(notebook.id),
}));


Як бачите - не складно. Але розмови, коли ми говоримо про швидкодію, нічого не варті - завжди треба міряти. Тому я зібрав цей код, протестував його на JsBench і вийшло, що перша реалізація на 98% повільніша ніж версія з Map. Якби ноутбуки продавалися з такою знижкою я б купив собі два :)

Так що, тепер переводимо все на мапи?

@reactbeginners
👍27🔥10
Free React For Beginners
Як цьому запобігти? (2/3) Для того щоб запобігти такій ситуації існує старий і прекрасний лайфхак - купити кращий комп'ютер - використати Map. Тобто трансформувати масив сутностей по якому у нас ведеться пошук у словник. Для того щоб знайти елемент у масиві…
Так що, тепер переводимо все на мапи? (3/3)

Звичайно що ні. Аде дуже навряд ви будете виводити 1000 ноутбуків на одну сторінку. Скоріше за все у вас буде paging або поступове завантаження.

ТОМУ:

Перший крок: оцінити реальну кількість елементів, з якою ви будете мати справу.

Другий крок:
порахувати складність алгоритму. Алгоритми зі складністю O(1) (взяти елемент по ключу або індексу) оптимізації не потребують, це й так максимум що можна витиснути. Алгоритми зі складністю O(N) (пошук елементу в масиві) скоріше за все теж можна не чіпати. А от якщо складність зростає до O(N*N), або ще гірше до O(N*N*N) це сигнал що оцінку потрібно продовжувати.

Третій крок: оцінити чи буде кількість ваших даних рости і до яких меж. Якщо кількість елементів не обмежена - скоріше за все потрібно оптимізувати. Якщо обмежена - переходимо до наступного кроку.

Четвертий крок: якщо кількість ваших даних обмежена - уявіть собі найгірший сценарій і протестуйте* поведінку коду в найгірших умовах. Якщо вас все влаштовує - видихаємо спокійно, якщо код "тормозить" - скоріше за все також потрібна оптимізація.

І останній крок: якщо оптимізувати довелося - залишаємо коментар в якому вказуємо навіщо ми це робили.

Як бачите - не дуже складно (а якщо щось не зрозуміло - я готовий пояснити це ще раз, просто запитайте у коментарях), і ще й наочно демонструє користь таких начебто теоретичних знань в повсякденній розробці.

На цьому у мене все, сподіваюся було корисно. І нагадаю, що користь матеріалу я визначаю по лайках :)

* З тестуванням є нюанс - зазвичай ми тестуємо на комп'ютерах розробників, а вони досить потужні. Тому, якщо не "тормозить" у вас, це не гарантія що не буде проблем у користувачів. Використовуйте CPU throttling в Chrome Dev Tools для більш точної оцінки.

@reactbeginners
👍61🔥12
Мій акаунт в twitter закривається:

Сьогодні Елон Маск закликав своїх прибічників звертатися до Сенату США щоб зупинити допомогу Україні. Це настільки мерзенно, що у мене майже немає слів.
Тому я закриваю свій акаунт в Твітері і зроблю все щоб жодна з компаній де я буду працювати, ніколи не мала з ним справу.

Вибачайте за політику, це вже занадто.

https://twitter.com/drag137/status/1757348056943525948
👍100❤‍🔥17🤝7
Forwarded from Той самий Бабіч (Сергій Бабіч)
#анонс
Онлайн співбесіда наживо рівня Strong Junior ReactJS з Дмитром Тілугом — переможцем другого випуску нового проєкту "Резюме Ґриль"!

Із провідного спеціаліста в авіаційній сфері до frontend розробника. Дмитро вирішив, що це хороша ідея і після успішної 10-ти річної карʼєри кардинально змінив професію. Не боїться казати “не знаю” на співбесідах та займається прибиранням заради задоволення.

А як ви раптом втомилися від запитань по самісінькому React, то маю вас втішити — готую нові й цікаві питання, тож нагостріть вушка!

***
А таємний експерт цього етеру — з компанії Svitla Systems, глобальної IT-компанії з більш ніж 20-річним досвідом, головний офіс якої знаходиться в Каліфорнії, а операційна діяльність поширюється на більш ніж 10 країн, зокрема США, Канаду, Мексику, Коста-Ріку, Аргентину, Україну і Польшу.

Svitla об’єднує понад 1000 спеціалістів з різних технологій. Серед клієнтів як інноваційні стартапи, так і компанії із Fortune 500.

***
⚡️ Strong Junior ReactJS // Співбесіда наживо // Дмитро Тілуг
16 лютого, 19:00
📺 Сергій Бабіч та Дивовижний світ веброзробки
👍20🔥7😁2❤‍🔥1
Іноді в Next.JS буває потрібно виконати якийсь код лише на клієнті. Як це зробити?

Перший варіант: застосувати справжні клієнтські компоненти за допомогою прапорця SSR:false та use client; Але це крайній варіант, тому що весь компонент буде виключений із первинного рендеру на сервері.

Другий варіант: виконати цей код в середині useEffect. За загальним правилом, ефекти виконуються виключно на клієнті і ви можете безпечно звертатися до, наприклад, об'єкту window або document. Але цей варіант не спрацює, якщо вам потрібно виконати код до ініціалізації React застосунку.

Тому існує третій варіант:
if (typeof window !== 'undefined') {
console.log(`HELLO CLIENT`);
}


В середині цього if ви також можете безпечено працювати з DOM API.

А от перевірка накшталт if (window?.addEventListener) вже не спрацює, ви отримаєте помилку ReferenceError: window is not defined

Майте це на увазі.

@reactbeginners
13👍6
Опублікував я вчора на LinkedIn пост про ноутбуки і зустрів два цікавих коментаря на цю тему

Перший:
Якщо фронтенд розробник читає книги про алгоритми, то його треба гнати з роботи, бо він готується бігати по співбесідах ) Бо типу більше ніж на співбесідах це ніде не потрібно


Другий (мовою оригіналу, вибачайте) про книгу "Грокаємо Алгоритми":
Книжечка конечно красивая, показывает причастность читателя к миру айти и достойна лайка, ну а серьезно, как часто эти алгоритмы нужны в реальной жизни, а не на собеседовании, когда все уже заложено в библиотеках и фреймворках?


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

Так от що я хочу сказати - це дуже далеко від істини.

І світ, і розробка зараз розвиваються дуже активно. Постійно з'являються та удосконалюються нові речі - штучний інтелект, машинний зір, системи автоматичного прийняття рішень (привіт Тесла), квантові обчислення та багато іншого. Та що далеко ходити - автонаведення дронів по не людям. Думаєте це роблять якісь вчені? Такі ж хлопці та дівчата як ми з вами! І таких задач багато, вони продовжують з'являтися. А за рахунок можливості працювати віддалено - ви цілком можете прийняти участь у їх вирішенні.

Але щоб прийняти участь - потрібно вчитися і алгоритми разом зі структурами даних є частиною цього навчання. Банально, якщо ви не знаєте популярних алгоритмів пошуку шляху, скоріше за все ви не створите кращий. Якщо ви не знаєте які є моделі для роспізнавання і як вони працюють, ви не дотренуєте свою до найкращого результату. І для цього вам навіть не треба вчити іншу мову - більшість із цього доступна з JavaScript-ом)

Тому не вірте тим, хто каже що все вже винайдено, або це лише для обраних. Вчіться, пробуйте, вибирайте і буде вам і щастя і цікава робота.

ПМ. Перший коментар взагалі якийсь рабовласницький, не хотів би я мати такого менеджера
ППМ. І ходіть на конференції, вони чудово розширюють кругозір і показують як багато чого нового та цікавого навкруги


@reactbeginners
45👍10🔥1
Тут один із наших підписників декілька місяців тому зробив свій телеграм канал про JavaScript.

Реклами у нас немає, але порекомендувати дружній канал з корисним тематичним контентом про JS/HTML/CSS думаю буде не гріх. Тим паче це ще й "найкращий" канал, ну як тут втриматися 😅

То ж запрошую до ознайомлення, можливо вам буде корисно)
👍162
Apple вимикає нормальну підтримку PWA (progressive web app) застосунків, мотивуючи це неможливістю забезпечити безпеку користувачів у випадку використання не сафарі браузера)

От так от легким помахом ноги велитенська купа роботи інших людей іде в смітник.

Тепер pwa-шки будуть відображатися як звичайні вкладки.

Обожнюю підхід еппл - це точно буде інтернет експлорер 2.0

І це стосується нас усіх, один дуже непоганий варіант зробити кросплатофрмений застосунок на react скоріше за все прикриють(
🤔154👍4
Понеділок, 19.02, 19:00 - нове відео про Next.JS: Практика з компонентами

Сьогодні виходить чергове відео з серії Next.JS. Цей раз подивимося на серверні та універсальні компоненти на практиці, напишемо кілька простеньких, подивимось де вони рендеряться.

Повний список виглядає зараз так:

Відео № 0.0 - Вступ до курсу Next.JS
Відео № 1.1 - Що таке Next.JS
Відео № 1.2 - [Практика] Мій перший застосунок
Відео № 2.1 - NextJs, компоненти та їх види
Відео № 2.2 - Справжні клієнтські компоненти в Next.JS
Відео № 2.3 - [Практика] NextJs, компоненти та їх види
Відео № 3.1 - заплановане на цей тиждень

Всім тихого тижня, бережіть себе та допомагайте ЗСУ!

@reactbeginners
27🔥9👍5❤‍🔥1
Любі друзі, перестаньте мучитися і мучити інших (І я зараз не про ввійти в айті).

Коли ви (або хтось) затягнули лібу, яка прямо дуже потрібна, але капець як не зручна - врятуйте світ, себе та команду: напишіть на неї обгортку. Просто напишіть компонент, або клас, що сховає від вас складність та спростить взаємодію з лібою/компонентом до прийнятного рівня. Так, потрібно буде трохи більше часу, так, треба буде подумати і можливо поговорити з командою як зробити краще. Але воно того варто на всі 100% і окупиться вже наступного разу коли вам або комусь доведеться працювати з цим компонентом.

Якщо цього не зробити, костилі до цієї ліби розповзуться по всьому проекту і будуть вам заважати працювати не лише з цією бібліотекою, а й з кодом що просто лежить поруч. А перероблювати потім це окреме коло пекла. Тому не треба так, просто повірте.

Не соромтеся, ставтеся до коду як до свого інструменту: вам має бути зручно з ним працювати, бо якщо у вас з очей йдуть криваві сльози - хтось точно повернув не туди.

Пішов страждати далі, ваш @reactbeginners
👍394🕊3💯2
А ну давайте маленький тестик

Як ви знаєте, в #React функціональні компоненти рендеряться заново, в тому числі, коли рендериться їх батьківський компонент (якщо не використовувати React.memo)

Тепер власне тест:

Маємо звичайний, майже класичний React counter:

function Counter({ children }) {
const [c, setCounter] = useState(0);
const increment = () => setCounter(c + 1);
return (
<button onClick={increment}>
{children} {c}
</button>
);
}


Єдиний нюанс з ним - він приймає в пропс children, який відмальовує всередині. В середину ми передаємо отакий примітивний компонент:

function ClickMeText() {
console.log('ClickMeText rendered');
return <>Clicked: </>;
}


Цей компонент - просто текст, який також містить консоль лог, щоб ми бачили коли він рендериться. В цілому виглядає це так:

const App = () => <Counter>
<ClickMeText />
</Counter>


Тепер питання: Я запустив сторінку та ТРИЧІ клікнув на каунтер. Скільки ClickMeText rendered я побачу в консолі, за умови що strict mode вимкнено?

1 раз - ставимо ❤️
3 рази - 👍
4 рази - 🔥

З вас смайлики, з мене пояснення)
🔥8750👍13🤔1🍾1
Free React For Beginners
Почнемо з короткого демо того, скільки разів буде перерендерений наш текстовий компонент😉 А от чому вийшла саме така кількість - питання набагато цікавіше)
То ж чому один раз? На справді, все досить просто

Перше що потрібно зрозуміти це те, що React.children це звичайний пропс, який приймає все що завгодно. Ви можете покласти туди і текст, і масив і ReactNode, як ми робимо в цьому прикладі. ReactNode - в свою чергу, це не наш компонент, це результат обчислення нашого компоненту у формі об'єкту. Ви можете зробити console.log(children) і подивитися що в цього об'єкту в середині.

Коли ми натискаємо на кнопку, у нас змінюється стейт каунтеру, що відповідно до загальних правил, змушує його перерендеритися. А що відбувається з пропсами, які нам передали згори? Та нічого, вони залишаються ті самі що й були, тому що вони належать батьківському компоненту, а цей батьківський компонент не змінюється.

Саме тому ми і бачимо ClickMeText rendered один єдиний раз. Спочатку рендериться <App/>, потім рендериться <ClickMeText/>, потім рендериться <Counter/> в який через пропс потрапляє результат обчислення <ClickMeText/>. Коли ми натискаємо на кнопку, змінюється стейт <Counter/> і він, Counter, обчислюється заново. Але в пропси передаються ті самі значення що й минулого разу.

Ось і уся магія, сподіваюся пояснення вийшло відносно простим.

Доречі, англійською, є дуже гарна стаття на цю тему для тих кому цікаво подивитися трохи глибше. Дякую пану Євгену за посилання.

@reactbeginners
👍45
😍 Отак от - TypeScript мова року за темпами зростання популярності

За рік TypeScript набрав 1.8%, досяг 15.1% відсотка користувачів і підійшов у притул до лідера. А лідер вгадайте хто? Правильно JavaScript яким користується, наразі, 15.4% розробників.

Що тут скажеш, TypeScript набирає своє і не без причини. Звичайно у нього є свої недоліки та tradeoff, але погодьтеся, з ним набагато приємніше працювати, коли проект хоч трохи розвинувся.

А от якої п'яної миші 1С зріс на 0.1% я зрозуміти не можу 😢

До чого це я? Вчіть TypeScript, він корисний! ❤️‍🔥

Детальну аналітику можна подивитися на DOU

@reactbeginners
👍305❤‍🔥1
Робили давненько і щось захотілося мені повторити, в світлі останніх подій.

Тому запрошую усіх бажаючих, в цей четвер, 22.02, на 19:00 поговорити про вогнепальну зброю для початківців.
Вхід - будь-який донат від 20 грн на збір мого колеги Ігоря Б на машину для ЗСУ.

Поговоримо про:

1. Види зброї в цілому
2. Першу зброю для початківця
3. Отримання дозволу на вогнепальну зброю


Запису не буде, місця обмежені - максимум 15 людей. Запрошення в зум кину в ТГ завтра після обіду.

Якщо у когось є питання накшталт "Чому це фронтендщик щось планує задвигати за зброю" - зможете задати це питання завтра.

💰Банка
✍️Реєстрація

Побачимося завтра
👍16❤‍🔥3🔥2
Тут пан Едуард, під відео про Next задав гарне запитання:

Чому next одразу не зробив нормальні компонети, які б рендерилися тільки на клієнті? Навіщо ці танці з бубнами? )) не зрозуміло.

Я саме про це деякий час думав і прийшов до дуже простого висновку, щодо якого хотів би почути і вашу думку.

Моя ідея полягає в тому, що сучасний Next.JS не націлений на інтерактивність як таку. Дивіться самі - з новим оновленням Next.JS всі компоненти, за замовчуванням, перетворюються на серверні. А серверні компоненти взагалі не можуть мати жодної доданої поведінки. Тобто самі розробники нам буквально кажуть - за замовчуванням, всі твої компоненти мають бути статичними!

І, я не вірю що це випадковість або якийсь недолік в проектуванні - скоріше за все цей підхід багато разів обговорювався і здався розробникам цілком прийнятним.

Якщо ж цей підхід прийняти, то все стає набагато простіше:

Не потрібно мучитися зі стейтам, з CSSinJS (інтерактивність же не потрібна), все працює з коробки. А залишки інтерактивності (якісь форми, менюшки, каруселі) можна робити або нативними компонентами, які працюють (use server як раз на це натякає), або окремими мікроелементами які можна просто поставити з NPM, бо екосистема дозволяє.

Що думаєте з цього приводу?
🔥762👍1