Это затычка для компилятора. Свойство может быть вообще не инициализировано, но TS будет об этом молчать. По-хорошему этот оператор стоит везде избегать, в TS хороший вывод типов.
Мы большинство проектов уже перевели на Vite и удивились тому, что фронтенд может быть быстрым, CI не занимает вечность, а шутки про ноутбуки, взлетающие как вертолёт при запуске проекта, можно наконец-то забыть.
Доказывать бесполезность TS через аналогию (или вообще доказывать что-либо через аналогию) - это демагогия, а не аргументация.
Typescript может быть полезен при разработке модулей для других разработчиков, так как это позволяет получить подсказки в стиле IntelliSense от IDE
А код в обычных приложениях вы только для себя пишите? Другие разработчики с вашими модулями не работают или других разработчиков просто нет? В этом и заключается одно из преимуществ типизации - вы перекладываете информацию, которая доступна только у вас в голове, в код, который потом будут читать другие. А в случае несоответствий контрактов между модулями компилятор вас об этом предупредит.
Ранее популярной опцией был также Material UI, но он уже несколько приелся, да и развивается не очень активно.
Вот на основании чего вы решили, что MUI не развивается? Смотрим статистику за последний месяц:
Так проблема не в Wordpress, а в том, что Gravatar использует числовые ID (которые легко перебирать в цикле в отличии от UUID) + отдаёт слишком много данных по запросу http://en.gravatar.com/ID.json. В статье так же указано, что Gravatar используется в GitHub.
Зашёл в документацию - ничего не понял. Что это за инструмент? Какую проблему решает? Даже несколько раз кликнул на главную с целью найти описание. Но описания нет, сразу пишем какой-то код.
Так студенты ведь ещё учатся, разве можно их назвать программистами? :) Для будущих абитуриентов было бы полезнее почитать о том, где учились уже состоявшиеся известные программисты и получали ли они высшее образование вообще. Немалая часть моих одногруппников-программистов вообще поступили с целью откосить от армии. Конечно на публику такой вариант ответа в вашем опросе никто из студентов не озвучит.
Откуда это слепое убеждение, что иммутабельность лучше мутабельности? В любом мало-мальски известном и навороченном движке для разработки игр используются махровое ООП с классами и прямые мутации стейта. Только веб-разработчики почему-то решили, что двигать кнопки и клепать формы на 3 поля нельзя с мутабельным подходом, нужен обязательно иммутабельный.
"Например, если мы захотим хранить ту же историю изменений в каком-нибудь редакторе."
Если вы хотите хранить историю изменений, то тут гораздо лучше подходит Immer от автора Mobx (так как Immer считает diff'ы между стейтами), а не Redux, который будет запоминать N-последних слепков всего стейта. В документации к Redux пишут, что с ним легко делать undo, но на практике это будет отъедать всю память, об этом в том числе писал и сам Абрамов: https://twitter.com/dan_abramov/status/1295823989542211590
Картинка со стейт-менеджерами вводит в заблуждение. Ни zustand ни recoil никогда не были популярны в React-сообществе и уж тем более никто не считал это стандартом. На продакшене вы эти технологии не встретите.
Но в Angular такой проблемы нет, Injectable-сервисы прекрасно справляются с этой задачей.
Injectable сервисы нужны для того, чтобы шарить состояние между деревом компонентов. Эти сервисы никак не отвечают за оповещение компонентов об изменениях. За это отвечает Zone.js — самая глупая система оповещения изменений, которую только можно найти в современных фреймворках. Почему глупая? Потому что это monkey patching и потому что обновления компонентов не точечные. Умная система оповещения изменений знает какой компонент от какого значения зависит и обновляет компоненты точечно (Mobx / Vue).
Да, в самом языке уже есть примитивы, которые позволяют работать с DOM напрямую, но такая разработка может подойти для индивидуальных разработчиков, а не для больших команд.
А как вы всё это время разрабатывали если платформа вас так ограничивает? По поводу локальных стейт-менеджеров — напишите свой. Или рассмотрите альтернативы — давным давно (по меркам фронтенда) существует Mobx, с которым тоже можно использовать локальные сторы. Порт на Dart: github.com/mobxjs/mobx.dart
TypeScript конечно в разы богаче, чем Dart — union типы, mapped типы, условные типы. Но ради этого переписывать кодовую базу на 2.5 миллиона строк…
4 из 5-и недостатков ООП на самом деле недостатки наследования. Пишите на ООП без наследования, даже подход такой есть — Composition Over Inheritance: en.wikipedia.org/wiki/Composition_over_inheritance
5-й недостаток ООП это доказательство через аналогию. Доказательством такое утверждение являться не может по определению. Аналогии — оружие демагогов в споре.
Интересно почему не упоминули Mobx, который и использует это идею с использованием геттеров, сеттеров и прокси ради перформанса и автоматических подписок.
чем больше есть возможностей декомпозиции тем лучше.
Код более поддерживаемый когда он имеет не только низкую связанность (coupling), но и высокую связность (cohesion): medium.com/clarityhub/low-coupling-high-cohesion-3610e35ac4a6
Это значит, что код, который меняется вместе, должен быть рядом. Следствием этого и появились компонентные фреймворки, позволяющие писать HTML / JS / CSS рядом — в одном или нескольких файлах, у которых высокий cohesion. И разделение ответственности это не о том, чтобы разделять ради разделения, а о том, чтобы при изменени одного модуля не нужно было править другие, несвязанные с этим модули: www.didoo.net/wp-content/uploads/2017/02/separation-of-concerns-800x522.png
В контексте стейт-менеджеров я плохо представляю ситуацию когда стейт существует без экшнов или экшны существуют без стейта. Или когда вычисляемые значения зачем-то держат отдельно от стейта (без которого они никогда не используются). Поэтому подход Mobx более удачный — computed / action / state в одном файле.
Если вы подробно ознакомитесь с паттерном проектирования observer, то поймете что явное указание подписчиков в слушателе является более правильной практикой.
Там пример для бекенда и там ни слова о том, что это более правильная практика — на бекенде по-другому нельзя. На фронте можно вычислять зависимости изменяемых значений через прокси. Именно благодаря им Mobx и запоминает какие компоненты от каких изменяемых значений зависят. Подход называется Transparent Reactive Programming: github.com/mobxjs/mobx/wiki/Mobx-vs-Reactive-Stream-Libraries-(RxJS,-Bacon,-etc)/
Ручная подписка на определенные состояния помогает избежать незапланированных перерисовок компонента.
Ручная подписка как раз может привести к незапланированным перерисовкам компонента, например вы удалили стор из компонента, но забыли удалить его из списка зависимостей у функции observer. У Transparent Reactive Programming этой проблемы нет.
А зачем? Что бы ваш код было сложней поддерживать?
Нет, 2 и более инстанса стора — вполне частая ситуация. Простой пример — сделайте 2 счётчика на странице, независимых, но с одинаковой логикой и без копипаста кода. В Mobx это 2 разных инстанса одного и того же класса.
Зачем имплементировать встроенный state-managment React совместно со стейт-машиной mobx
useState здесь это простой способ сохранения значения между перерисовками. Лишь один из способов использовать Mobx. Встроенный хук useLocalObservable делает тоже самое: github.com/mobxjs/mobx/blob/main/packages/mobx-react-lite/src/useLocalObservable.ts#L8
Стор можно добавить в контекст реакта, тогда он будет глобальным и useState не нужен. Это к Mobx не относится, это лишь способ использовать его в одном из UI-фреймворков.
но ваш store предоставляет мутабельное поле value во внешний мир, Нарушая принцип инкапсуляции.
Это поле никто извне поменять не сможет — Mobx в строгом режиме (по умолчанию в версии 6) запретит изменять его вне экшнов. Ещё никто не мешает создать класс с приватным свойством. Для простого примера это было лишнее.
Но если вы разрабатываете более крупный проект, над котором работают смежные команды, то от всей этой архитектурной свободы вы скорее всего получите максимум боли
Не понимаю зачем включать в статью голословные заявления и объяснять это субъективным мнением. Мнение без аргументов бесполезно и вредно. Касательно вашего примера — какой смысл разделять стор от экшенов? Зачем прокидывать экшны в аргументы observer? Что за странная конвенция импортировать connect как adapter и добавлять его в массив middleware? У вас стор импортируется из модуля инициализированный, как мне создать 2 инстанса стора (пример — 2 независимых инстанса duck)? Как написать юнит-тест на стор, не сбрасывая его состояние перед каждым тестом? Напоминаю, что импорт из модуля делает стор синглтоном. Почему экшн duckQuack переименовался в setQuack? При чтении кода возникают регулярные WTF, которые не возникают при чтении кода на Mobx:
Работает действительно быстрее, жаль что Vite не запускает TypeScript и проверять ошибки типов нужно отдельным процессом:
Vite only performs transpilation on .ts files and does NOT perform type checking. It assumes type checking is taken care of by your IDE and build process (you can run tsc --noEmit in the build script).
Какие критические вещи в Create React App висят годами? Там хотя бы строгий режим TS включён по умолчанию + новый ESLint, а в Angular CLI до сих пор TSLint устаревший и нестрогий TypeScript. В Angular есть автоматические миграции, но в React гораздо реже ломают обратную совместимость, не говоря уже о том, что у Angular мажорные (то есть ломающие) версии выходят раза в 3-4 чаще, чем в React.
Это затычка для компилятора. Свойство может быть вообще не инициализировано, но TS будет об этом молчать. По-хорошему этот оператор стоит везде избегать, в TS хороший вывод типов.
Есть хотя бы один мейнстримный статически типизированный язык, который может то, что вы просите?
В 2021-2021 тренд на тулинг для JS, написанный не на JS. И это не просто поделки энтузиастов, а уже работающий в продакшене код. Например тот же esbuild (написан на Go) уже используется в Vite и даже Angular: https://blog.ninja-squad.com/2021/08/04/angular-cli-12.2/
А Next.js использует SWC (написан на Rust): https://nextjs.org/docs/advanced-features/compiler
Мы большинство проектов уже перевели на Vite и удивились тому, что фронтенд может быть быстрым, CI не занимает вечность, а шутки про ноутбуки, взлетающие как вертолёт при запуске проекта, можно наконец-то забыть.
Доказывать бесполезность TS через аналогию (или вообще доказывать что-либо через аналогию) - это демагогия, а не аргументация.
А код в обычных приложениях вы только для себя пишите? Другие разработчики с вашими модулями не работают или других разработчиков просто нет? В этом и заключается одно из преимуществ типизации - вы перекладываете информацию, которая доступна только у вас в голове, в код, который потом будут читать другие. А в случае несоответствий контрактов между модулями компилятор вас об этом предупредит.
Вот на основании чего вы решили, что MUI не развивается? Смотрим статистику за последний месяц:
https://github.com/mui-org/material-ui/pulse/monthly
152 Merged pull requests | 71 Open pull requests | 133 Closed issues | 86 New issues
https://github.com/chakra-ui/chakra-ui/pulse/monthly
51 Merged pull requests | 7 Open pull requests | 52 Closed issues | 19 New issues
Почему вся статья про "Профессиональный React" состоит из голословных утверждений и субъективного мнения?
До сих пор видео-звонки часто начинаются с фраз "Как меня слышно?", о какой метавселенной речь?
Так проблема не в Wordpress, а в том, что Gravatar использует числовые ID (которые легко перебирать в цикле в отличии от UUID) + отдаёт слишком много данных по запросу http://en.gravatar.com/ID.json. В статье так же указано, что Gravatar используется в GitHub.
Зашёл в документацию - ничего не понял. Что это за инструмент? Какую проблему решает? Даже несколько раз кликнул на главную с целью найти описание. Но описания нет, сразу пишем какой-то код.
Отличные статьи, всегда интересно читать!
Так студенты ведь ещё учатся, разве можно их назвать программистами? :) Для будущих абитуриентов было бы полезнее почитать о том, где учились уже состоявшиеся известные программисты и получали ли они высшее образование вообще. Немалая часть моих одногруппников-программистов вообще поступили с целью откосить от армии. Конечно на публику такой вариант ответа в вашем опросе никто из студентов не озвучит.
Откуда это слепое убеждение, что иммутабельность лучше мутабельности? В любом мало-мальски известном и навороченном движке для разработки игр используются махровое ООП с классами и прямые мутации стейта. Только веб-разработчики почему-то решили, что двигать кнопки и клепать формы на 3 поля нельзя с мутабельным подходом, нужен обязательно иммутабельный.
"Например, если мы захотим хранить ту же историю изменений в каком-нибудь редакторе."
Если вы хотите хранить историю изменений, то тут гораздо лучше подходит Immer от автора Mobx (так как Immer считает diff'ы между стейтами), а не Redux, который будет запоминать N-последних слепков всего стейта. В документации к Redux пишут, что с ним легко делать undo, но на практике это будет отъедать всю память, об этом в том числе писал и сам Абрамов: https://twitter.com/dan_abramov/status/1295823989542211590
TypeScript конечно в разы богаче, чем Dart — union типы, mapped типы, условные типы. Но ради этого переписывать кодовую базу на 2.5 миллиона строк…
5-й недостаток ООП это доказательство через аналогию. Доказательством такое утверждение являться не может по определению. Аналогии — оружие демагогов в споре.
Это значит, что код, который меняется вместе, должен быть рядом. Следствием этого и появились компонентные фреймворки, позволяющие писать HTML / JS / CSS рядом — в одном или нескольких файлах, у которых высокий cohesion. И разделение ответственности это не о том, чтобы разделять ради разделения, а о том, чтобы при изменени одного модуля не нужно было править другие, несвязанные с этим модули: www.didoo.net/wp-content/uploads/2017/02/separation-of-concerns-800x522.png
В контексте стейт-менеджеров я плохо представляю ситуацию когда стейт существует без экшнов или экшны существуют без стейта. Или когда вычисляемые значения зачем-то держат отдельно от стейта (без которого они никогда не используются). Поэтому подход Mobx более удачный — computed / action / state в одном файле.
Там пример для бекенда и там ни слова о том, что это более правильная практика — на бекенде по-другому нельзя. На фронте можно вычислять зависимости изменяемых значений через прокси. Именно благодаря им Mobx и запоминает какие компоненты от каких изменяемых значений зависят. Подход называется Transparent Reactive Programming: github.com/mobxjs/mobx/wiki/Mobx-vs-Reactive-Stream-Libraries-(RxJS,-Bacon,-etc)/
Ручная подписка как раз может привести к незапланированным перерисовкам компонента, например вы удалили стор из компонента, но забыли удалить его из списка зависимостей у функции observer. У Transparent Reactive Programming этой проблемы нет.
Нет, 2 и более инстанса стора — вполне частая ситуация. Простой пример — сделайте 2 счётчика на странице, независимых, но с одинаковой логикой и без копипаста кода. В Mobx это 2 разных инстанса одного и того же класса.
useState здесь это простой способ сохранения значения между перерисовками. Лишь один из способов использовать Mobx. Встроенный хук useLocalObservable делает тоже самое: github.com/mobxjs/mobx/blob/main/packages/mobx-react-lite/src/useLocalObservable.ts#L8
Стор можно добавить в контекст реакта, тогда он будет глобальным и useState не нужен. Это к Mobx не относится, это лишь способ использовать его в одном из UI-фреймворков.
Это поле никто извне поменять не сможет — Mobx в строгом режиме (по умолчанию в версии 6) запретит изменять его вне экшнов. Ещё никто не мешает создать класс с приватным свойством. Для простого примера это было лишнее.