Comments 25
Внешний стор - антипаттерн
Лучше когда каждый компонент может хранить своё состояние сам и отображаться по разному в разных контекстах
а откуда компонент будет брать эту "разность"?
От родительского компонента
Это точно так же как работать с чужой либой или апи, аналогия такая
Т.е. вы в родительском компоненте (со всей этой вьюшной декларативностью) собираетесь хранить талмуд на тему того, каким образом различные дочерние компоненты должны в нём отображаться?
У вас довольно специфичное представление об "антипаттернах" ;)
К тому же логическое противоречие:
каждый компонент может хранить своё состояние сам
От родительского компонента
Ну примерно так https://github.com/b-on-g/blitz/blob/master/blitz.view.ts
namespace $.$$ {
// Activate path-based URL routing (no `#!`).
void $bog_ui_router_path
export class $bog_blitz extends $.$bog_blitz {
@$mol_mem
tools() {
const is_host = this.Lobby().is_host()
return [is_host ? this.Radio() : null, this.Feedback_link(), this.Settings()]
}
screen_body() {
const page = (this.pages() as Record<string, any>)[this.screen()]
return page ? [page] : []
}
screen(next?: string) {
if (next !== undefined) {
this.mobile_menu_showed(false)
if (next === 'lobby') {
this.$.$mol_state_arg.value('quiz', null)
}
}
return this.$.$mol_state_arg.value('screen', next || undefined) || 'admin'
}
}
}Противоречия нет, состояние и у родителя есть и у дочернего компонента, родитель меняет дочерний в зависимости от контекста
На самом деле Алексу нужно задуматься вот о чем. Pinia прививает очень плохую практику, в которой стор "и швец и жнец и на дуде игрец", то есть он:
Инициализирует данные
Выполняет запрос к другим данным
Меняет собственное состояние
В идеале нужно было бы подойти с такой точки зрения:
Что в этом сторе является БЛ, а что – логикой стора
какие данные стор хранит и как их получает
как данные нормализуются при записи и какой тип является «контрактом» стора
кто имеет право мутировать состояние — стор сам через методы, или кто угодно снаружи напрямую
какие вычисления являются производными от состояния стора (computed), а какие — бизнес-логикой, которой в сторе вообще не место
какой тип является контрактом стора —
anyвообще не должен быть допустим,Record<string, unknown>— полумера. Нужно использовать явный интерфейс и типизировать через него хранилище. Если не получается – значит проблему надо решать уровнем выше, до написания сторавнешние элементы, включая композабл, не должны менять состояние стора напрямую — только через явные методы. Подход get/set никто не отменял
И взглянув на старый код
export const usePropertyStore = defineStore('property', () => {
const items = ref<Record<string, any>>({})
const isFetching = ref(false)
watch(
items,
(val) => {
localStorage.setItem('items', JSON.stringify(val))
},
{ deep: true }
)
const activeType = computed(() => localStorage.getItem('type'))
const currentItem = computed(() => {
if (!activeType.value) return null
return items.value[activeType.value]
})
async function load() {
isFetching.value = true
const result = await fetchProperties()
isFetching.value = false
return result
}
return { items, isFetching, activeType, currentItem, load }
})
мы неожиданно поймем, что в сторе должно быть примерно так:
interface Property {
typeId: string
label: string
// ... остальные поля
}
interface RawProperty {
type_id: string
name?: string
// поля как приходят с API — snake_case, необязательные
}
export const usePropertyStore = defineStore('property', () => {
const items = ref<Property[]>([])
const activeType = ref<string | null>(null)
const currentItem = computed(() => items.value.find(p => p.typeId === activeType.value) ?? null)
function _normalize(raw: RawProperty[]): Property[] {
return raw.map(p => ({
typeId: p.type_id,
label: p.name ?? 'Unknown',
// остальные поля
}))
}
function setItems(raw) {
items.value = _normalize(raw)
}
return { items, setItems, activeType, currentItem }
})
find здесь не случаен — он явно выражает намерение: найди элемент по условию. Индексный доступ items[key] выражает другое: возьми по заранее построенному ключу, и тогда ты несёшь ответственность за консистентность этой структуры. Массив с find честнее: источник правды — список, поиск — производная операция. Если завтра условие усложнится (например, искать по typeId и regionId), массив расширяется тривиально, а Record потребует смены ключа и рефакторинга всех мест записи.
В идеале надо смотреть в сторону того, что стор может явно иметь функции для нормализации (чтобы привести входящие данные к контракту) и дальше только методы чтения/записи, использующие типы для того, чтобы извне сообщать структуру. RawProperty и Property могут и должны отличаться — граница между ними и есть зона ответственности нормализатора.
Остальную логику вытаскивать в композабл и переиспользовать (он же и должен возвращать стор — делаем компонент, который агностичен к стору, т.е. напрямую со стором не взаимодействует). Так, если логика поменяется, стор не будет затронут, и взаимодействие с ним можно расширять без риска что-то сломать.
Когда оставляют длинные "— ", уже кажется, что это ИИ ответ. Это только первая часть рефакторинга, показывает мысли Алекса, на что можно опереться при рефакторинге. Чтобы полноценно рассказать все этапы рефакторинга, нужно тогда писать уже несколько статей.
И то на каждую статью найдется человек, который скажет, что всё неверно и не так вы мыслите, а на самом деле вот так должно быть. Тут уж правда зависит от любителя поспорить))
Ad hominem – вещь, конечно, интересная, но ведь можно рассмотреть вопрос того, что у собеседника макбук. Это уже давно не аргумент в пользу ИИ, полагаю у вас нет других аргументов в это.
Что по сути.
Я говорю лишь о том, что вы остановились на полпути, на симптомах, и даете статью как готовый мануал, от которого можно оттолкнуться, читатель унесет ее как образец. А в образце остались совершенно нетронутыми проблемы, которые как раз и стоило разобрать, и в которых работа с LS и watch отвалились бы самостоятельно.
Я просто захотел написать статью - я её написал. Что я не так сделал? Что мне теперь, нельзя выкладывать статью, если я вот так захотел?
Извините, я с вами спорить не буду продолжать. Если вы так считаете, то это ваше право. Будьте чуть подобрее, пожалуйста, в комментариях!
Есть инетерсная статья про стор: https://habr.com/ru/articles/1020074/
А так истина зависит от проекта и от текущих требований. К сожалению, нет одного правильного ответа: вот так хорошо, а вот так плохо))
Забавно, что именно этот ключевой тезис почему-то постоянно упускают в подобных статьях и обсуждениях)) Ну либо классическое "в моём проекте именно так, а значит так должны делать все! ну или вы попросту не работали с серьёзными проектами" ;)
Что-то не вижу того, что мой образец – идеальный. Вроде и не говорю, что это идеальное решение, которое всем подойдет. Вопрос в том, что в рефакторе нужно отталкиваться не столько от практик, сколько от того, чем является стор, для чего он предназначен, что с этими данными БЛ делает. И отсутствие этих границ — это выстрел в ногу. А пока что автор не особенно-то и рассматривает эти границы, хотя паттерны про изоляцию слоев и нормализацию данных не является оверинжинироингом.
Почему вас (как и многих) постоянно уносит в дебри теоретических абстракций?
Вопрос в том, что в рефакторе нужно отталкиваться не столько от практик, сколько от того, чем является стор, для чего он предназначен, что с этими данными БЛ делает.
А как по мне, отталкиваться надо от целого комплекса причин. Главная из которых - решение поставленной бизнес-задачи в рамках доступных трудозатрат ;)
А ещё границы могут плавать - и тогда приходится переопределять саму базовую концепцию стора. Вас такое наверное в ступор вводит? Но это вполне распространённое явление))
Вы вот даже абстрактный пример на TS привели. А я считаю его использование явно избыточным (см. вышеозвученную первопричину) для многих (не для всех) проектов.
Т.е. вы во главу угла ставите концептуальную чистоту, а я гибкость.
А я считаю его использование явно избыточным (см. вышеозвученную первопричину) для многих (не для всех) проектов.
Считать TS избыточным в современном фронтенде — это, конечно, сильно. Это уже давно инструмент для онбординга, который отлично снижает трудозатраты в перспективе и никак их не увеличивает.
А ещё границы могут плавать - и тогда приходится переопределять саму базовую концепцию стора.
В этом-то и прикол: строгие контракты позволяют логике плавать как угодно и эволюционировать безболезненно. Если вы в строгом контракте меняете реализацию внутри, вы этим не ломаете логику потребителей.
Вас такое наверное в ступор вводит?
Меня мало что в ступор вводит. Писать непродуманно — это распространенная ситуация, с которой я стараюсь бороться.
Главная из которых - решение поставленной бизнес-задачи в рамках доступных трудозатрат ;)
Отказ от контрактов и TS (который вы почему-то считаете избыточным) экономит время только первые две недели проекта. Мало того, что это потенциально увеличит трудозатраты в дальнейшем при добавлении новой сущности/фичи, так еще и изменение бэка повлечет за собой набор багов, которые вы запаритесь отлавливать по всему проекту.
Удивительным образом вы пытаетесь продать техдолг и отсутствие границ зон ответственности ради мнимого "прагматичного решения бизнес-задач".
Да, границы, безусловно, могут плавать. Никто не предлагает строить космолет для лендоса. Но в итоге каждый сам волен решать: потратить 10 минут на продумывание логики стора сейчас, или тратить часы на дебаг потом, оправдывая это "доступными трудозатратами" на старте.
Считать TS избыточным в современном фронтенде — это, конечно, сильно. Это уже давно инструмент для онбординга
Что такое "онбординг"? Завязывайте вы с этим "англо-русским суржиком" - порой невозможно понять становится...
Это уже давно просто... дань моде!
который отлично снижает трудозатраты в перспективе и никак их не увеличивает.
А если перспектива не нужна? А вот на старте он как раз их резко увеличивает! А если у меня в проекте все типы данных под контролем - зачем мне TS?
В этом-то и прикол: строгие контракты позволяют логике плавать как угодно и эволюционировать безболезненно.
Абсолютно нет)) У вас может поменяться даже момент инициализации стора - и вся логика оказывается бесполезной - ей попросту не с чем работать!
Писать непродуманно — это распространенная ситуация
Писать сверхпродуманно - такая же распространённая ситуация, которая к тому же имеет привычку срывать все сроки ;)
Отказ от контрактов и TS (который вы почему-то считаете избыточным)
Представляете - я и JS считаю избыточным там, где справится CSS! Вы вообще понимаете суть пресловутой фразы "для каждой задачи - свой профильный инструмент". Строгая типизация - это не чёрный ящик с надписью "сделай всё хорошо, а плохо не делай". Блин, какой же зашоренный догматизм...
экономит время только первые две недели проекта
Вот! Уже сами за меня исключения из вашего догматизма подбираете))
так еще и изменение бэка повлечет за собой набор багов, которые вы запаритесь отлавливать по всему проекту.
Да хватит уже с этой мантрой носится! Я не первый год во фронтенде варюсь, чтобы вы мне тут идеализированные кейсы пересказывали. Завтра вам бэк отдаст данные как и положено в виде строки, только это будет просто число в кавычках и ваш лингвистический парсер сразу на нём глюкнет.
Удивительным образом вы пытаетесь продать техдолг и отсутствие границ зон ответственности ради мнимого "прагматичного решения бизнес-задач".
Удивительным образом вы поставили прилагательное "мнимый" совершенно не в том месте вашего тезиса ;) Вот как правильно:
Удивительным образом вы пытаетесь продать мнимый "техдолг" и отсутствие мнимых границ "зон ответственности" ради прагматичного решения бизнес-задач.
Никто не предлагает строить космолет для лендоса.
Вы не просто это предлагаете, вы ещё ожесточённо со мной спорите по этому поводу))
Но в итоге каждый сам волен решать: потратить 10 минут на продумывание логики стора сейчас
10 минут? Этот срок иногда днями измеряется и при этом все равно может быть оправдан. Разницу замечаете - я не скатываюсь в догматизм "правильно именно так!", я говорю об анализе самого верхнего мета-уровня - о выборе инструментария и методологии . У вас же инструментарий "по дефолту" уже определён - все размышления в итоге сводятся как именно проектировать в рамках уже устоявшейся парадигмы. Типичная профдеформация ;)
И вроде бы ничего плохого в этом нет - вам в вашем "крупном финтехе" вполне норм с таким подходом. Но зачем вы с умным видом пытаетесь навязывать этот подход как "единственно верный" всем остальным? У них могут быть задачи такой специфики, о которой вы даже не подозреваете...
Вместо ответа случайно лайк поставила... не хотела, не хотела
Что такое "онбординг"? Завязывайте вы с этим "англо-русским суржиком" - порой невозможно понять становится...
я так понимаю, у вас люди никогда не меняются, все десятками лет на одной и той же позиции и вы сами сидите исключительно на одном проекте, что вам нужно объяснять, что такое онбординг? К словам не цепляйтесь
Это уже давно просто... дань моде!
Уже лет пять TS это стандарт индустрии, в каждой вакансии требуется знание TS. Но это дань... так и запишем...
Я тоже не первый год во фронтенде, и? В любом случае, вы уходите от обсуждения в плоскость эмоций. Но один ваш аргумент ну просто великолепен, потому что он доказывает мою изначальную мысль:
Завтра вам бэк отдаст данные как и положено в виде строки, только это будет просто число в кавычках и ваш лингвистический парсер сразу на нём глюкнет.
В этом и суть нормализации, которую я привела в своем комментарии. В этом также и суть типизации. TS описывает статический контракт (то, что UI ожидает), а нормализатор может подхватить сырые данные от бэка и привести к нужному виду безопасно для интерфейса.
Если проверку не делать, то этот глюк вы будете отлавливать не на этапе рантайма, а где-нибудь у юзера багнет в глубине интерфейса, и ищи-свищи, почему и как этот баг вылез.
Если вас так беспокоит писать самостоятельно, то есть GQL, есть ZOD в конце концов.
А если перспектива не нужна? А вот на старте он как раз их резко увеличивает!
Зачем приводить в пример проекты, где "перспектива не нужна" в статье про стор? Там и VUE/REACT/ANG не нужен, если это такая однодневка, что у нее перспективы нет. Зачем туда вообще pinia затягивать и стейт-менеджмент?
Представляете - я и JS считаю избыточным там, где справится CSS!
Смотрим на предыдущий тезис. Вы приводите использование CSS там, где обсуждается использование инструментов, где CSS ну никак не поможет.
Другими словами присваиваете мне заочно то, о чем я вообще не говорила, чтобы выставить мое мнение как исходно некорректное или глупое) Если вы не можете оспорить по существу, то просто не отвечайте.
Вы не просто это предлагаете, вы ещё ожесточённо со мной спорите по этому поводу))
Цитируйте. Опять же, выдумки ради выдумок.
Разницу замечаете - я не скатываюсь в догматизм "правильно именно так!"
Есть статья, мне есть к чему придраться – я и придираюсь. Я предлагаю структуру, как бы беседуя с автором статьи через его же персонажа. Вы же выставляете так, будто я навязываю свою систему (а это не так, предложение видения – это не навязывание позиции).
Ну а говорить про парадигму и профдеформацию – это уже стендап, типичный ad hominem. У меня есть достаточно большой опыт в проектировании и работе с реальными интерфейсами, сложными и не очень, в обучении новых разработчиков, в кодревью и в целом экспериментирую (причем иногда прямо на работе) тоже очень много. Если вы это называете "догматизмом" – ок, называйте и надейтесь, что вы не будете тратить лишние часы на то, чтобы просто держать "в узде" свои проекты.
P.S. Я лично вашу позицию считаю куда более зашоренной и "догматичной". Только ваш догматизм проявляется в том, что вы хотите денег рубить за меньшее количество работы, чем у вас есть. И поэтому всякий зоопарк в проектах вас не особо напрягает. эдакий "эффект Гомера" у вас: проблемы, которые я сегодня не предусмотрел, будет решать будущий я.
Я же мыслю в той парадигме, как бы мне самой себе в будущем не добавить работы.
За сим откланяюсь, ваш переход на личности меня совершенно не радует.
я так понимаю, у вас люди никогда не меняются, все десятками лет на одной и той же позиции и вы сами сидите исключительно на одном проекте, что вам нужно объяснять, что такое онбординг?
Я последние годы в основном на фрилансе и аутсорсе. У меня, в отличие от вас, меняется вообще ВСЁ!
К словам не цепляйтесь
Буду! Поскольку я не понимаю какой смысл вы в них вкладываете)) Как иначе диалог вести?
Уже лет пять TS это стандарт индустрии, в каждой вакансии требуется знание TS. Но это дань... так и запишем...
Так... Пошла классическая апелляция к авторитетам (или как вы любите - argumentum ad verecundiam). Т.е. в догмы скатываетесь? О чём я вам и твержу ;)
Стандарт, видите ли... Бутстрап тоже стандартом был. Как и пре-процессоры... Ну что против такого "аргумента" предъявить... Разве только то, что когда начинаешь выяснять - "а зачем вам в этом конкретном проекте TS", то внезапно оказывается "ну я в этом не разбираюсь, наш бекендер так сказал"...
В этом и суть нормализации, которую я привела в своем комментарии. В этом также и суть типизации. TS описывает статический контракт (то, что UI ожидает), а нормализатор может подхватить сырые данные от бэка и привести к нужному виду безопасно для интерфейса.
Зачем вы мне это объясняете? Почему вы постоянно скатываетесь в менторский тон? TS обеспечивает вам только семантическую валидность, но не логическую.
Контрпример - у меня было проект где все(!) данные приходили с микроконтроллеров только строками. И на кой ляд мне здесь TS? Потому что гладиолус стандарт?
Смотрим на предыдущий тезис. Вы приводите использование CSS там, где обсуждается использование инструментов, где CSS ну никак не поможет.
Другими словами присваиваете мне заочно то, о чем я вообще не говорила, чтобы выставить мое мнение как исходно некорректное или глупое) Если вы не можете оспорить по существу, то просто не отвечайте.
Я привожу вам доступную аналогию принципа "KISS"! А вы её не считываете и начинаете меня заочно обвинять в потенциальной подмене тезисов)) Т.е. делаете ровно то, в чём пытаетесь обвинить меня)))
Так-то у нас изначально речь шла именно про pinia, но вас отчего-то возбудила возможность поспорить о "мастхэвности TS" - да не проблема, давайте побеседуем))
Зачем приводить в пример проекты, где "перспектива не нужна" в статье про стор?
Потому что стор - это не только про перспективу, а в основном про удобство разработки.
Там и VUE/REACT/ANG не нужен
Зачастую да))
если это такая однодневка, что у нее перспективы нет
И снова - а какое отношение реактивность данных имеет к перспективам развития и поддержки??? Скорее отрицательное ;)
Цитируйте. Опять же, выдумки ради выдумок.
Цитирую:
Считать TS избыточным в современном фронтенде — это, конечно, сильно. Это уже давно инструмент для онбординга, который отлично снижает трудозатраты в перспективе и никак их не увеличивает.
Никто не предлагает строить космолет для лендоса.
Где я что выдумал?
Вы же выставляете так, будто я навязываю свою систему (а это не так, предложение видения – это не навязывание позиции).
Да вы же сами чуть выше на некие мифические стандарты отрасли и требования HR ссылались))
У меня есть достаточно большой опыт в проектировании и работе с реальными интерфейсами
Но все они одного масштаба и специфики, не правда ли? ;)
Только ваш догматизм проявляется в том, что вы хотите денег рубить за меньшее количество работы, чем у вас есть
This! А для чего мне энтропию вселенной увеличивать лишними смыслами по Оккаму? Это скорее вы пытаетесь рубить больше денег за "стандарты индустрии", т.е. за пустышку - "мы же тут космолёт строим, не хухры-мухры", хотя самому бизнесу ваши гипердвигатели совершенно не упёрлись. Но вы зато очень умело научились вешать "методологическую лапшу" на уши - "без этого невозможно будет поддерживать! это решение не будет масштабироваться" ;)
проблемы, которые я сегодня не предусмотрел, будет решать будущий я.
This! Потому что всего предусмотреть невозможно! Просто я уже давно в этом варюсь - сегодня ты всеми силами пытаешься построить идеальную архитектуру стора, а завтра у тебя “node-sass deprecated”; сегодня пытаешься типизировать всё и вся, а завтра "извините, технология flash больше не поддерживается"...
Знаете, вы мне говорите про менторский тон, при этом сами неоднократно указываете, что у меня то опыт не такой, то его недостаточно, то я пальцы гну («я не первый год во фронтенде варюсь»), то у меня профдеформация — то есть мои аргументы можно по существу не рассматривать.
В одном соглашусь: любая технология устаревает, и BDUF может обесцениться вместе со стеком — это реальная проблема. Но это аргумент за стабильные контракты на границах, а не против них.
Идея ровно в том, чтобы инвестировать в то, что переживёт смену инструментов: типы данных и границы слоёв стабильнее, чем конкретные фреймворки. node-sass устарел, а понятие «нормализатор на входе данных» — нет.
Если есть содержательные контраргументы к нормализации, контрактам или разделению Raw/Domain типов — давайте по ним. Если нет — это не дискуссия, это перетягивание авторитета, и в ней мне неинтересно участвовать. Как и неинтересно спорить, «чей опыт ровнее».
Я неоднократно сказала, что пишу про подход в конкретной ситуации, и не предлагаю строить космолёты для лендосов. Но вы видите ровно то, что ставит вас в более красивую позицию.
Вы можете отвечать, конечно, но увы, я интерес к вашим аргументам потеряла вовсе. Бравируйте где нибудь в другом месте, пожалуйста.
Про теоретические абстракции смешно было. Я эту практику вижу не только у себя, но и в других крутых проектах
Ладно хоть не только у себя)) А "крутые проекты" - это вообще очень расплывчатое понятие ;)
Существует как минимум одна крупная компания в той же РФ, где активно применяется та логика, о которой я говорю. Ее продуктами пользуется более 22000 ритейлеров по РФ и еще сколько-то в СНГ, а сама компания входит в топ-5 интеграторов CRM систем. Дальше уже сами погуглите, что это может быть за компания.
Вы передо мной пальцы решили гнуть?)) Я, например, занимался разработкой продуктов для доброго десятка транснациональных гигантов - и насмотрелся при этом на всякое!
Да и зачем далеко ходить - давайте взглянем на кодовую базу того же Яндекса (Гугла, если хотите) - ну там же полный кошмар с точки зрения чистоты архитектуры... Бутерброд из адового легаси и "современных архитектурных подходов" ;)
Вы слишком многое о себе мните. Вы сказали "Только у себя". Я, без названия группы компаний, обозначила, что за компании такое практикуют. Более того, я там даже не работаю.
Если Дуров для телеграма использует один файл в котором все описано – это не значит, что это здоровый подход. Все равно, что говорить "ну вот чел на олимпиаде же золотую медаль выиграл, хотя курит как паровоз, значит курить – полезно для здоровья".
А вот когда вы уже заговорили про ваш опыт, то это. конечно, уважаемо, но не доказывает вашу правоту ни на йот.
Как не надо писать Store в Pinia (Vue). Разбираем на выдуманном примере