Comments 28
Вот только мемоизация любого из компонента убьет все ваше открытие. Кроме того оно не работает вверх по дереву. Используйте контексты или MobX и не страдайте.
Это не так. Каждый компонент подписывается на изменения стейта который в нём используется. Под копотом обычный state manager.
Используйте контексты или MobX и не страдайте.
Не надо использовать контексты для чего-то изменяемого. Используйте useSyncExternalStorage.
Не надо использовать контексты для чего-то изменяемого. Используйте useSyncExternalStorage.
Context только для того чтобы шарить ссылку на состояние верхнеуровневое(экземпляр класса) между дочерними компонентами.
export const CardItem = observer(() => {
const [state] = useState(() => new CardState());
return (
<CardStateContext.Provider value={state}>
<CardHeader />
<CardBody />
<CardFooter />
</CardStateContext.Provider>
)
})
const CardHeader = observer(() => {
const state = useContext(CardStateContext);
return (
<div className={styles.card_header}>
//...
<CardMenu />
</div>
)
})
const CardMenu = observer(() => {
const state = useContext(CardStateContext);
return (
<div className={styles.card_menu}>
//...
</div>
)
})
В таком духе.
Каким только извратом не страдают. Нет бы просто использовать MobX и context(только по назначению) и вообще не о чем не парится и не страдать.
Совсем разные задачи. Здесь людям предоставляется удобный дизайн описания кода, при котором переиспользуется знание хуков. В случае с mobx, что бы написать хороший код придётся выучить много нового. Порог вхождения совершенно разный.
Вообще ничего учить не надо. 10 минут документации и 10 минут экспериментов и готово.
class State {
counter = 1;
constructor() {
makeAutoObservable(this);
}
}
const state = new State();
setInterval(() => { state.counter++; }, 1000);
const Component = observer(() => {
return <div>counter value: {state.counter}</div>
});
Вообще элементарщина и всё работает как ожидается.
Я тоже знаю mobx. И считаю его вполне интересным решением, правда его идею с "makeAutoObservable" считаю не очень удачной, да и прокси вместо реальных данных мне тоже не нравятся. А так же остаётся запретить "autorun" на проекте и научить всех проектировать нормальное ООП. Но я очень уважаю mobx, они отличные ребята и держат марку.
да и прокси вместо реальных данных мне тоже не нравятся
import { configure } from "mobx"
configure({
useProxies: "never"
})
правда его идею с "makeAutoObservable" считаю не очень удачной
Я тоже по началу так считал, но теперь мне наоборот нравится, кода меньше и код чище. Но я использую свою функцию вместо makeAutoObservable, которая делает тоже самое, только c deep: false и вместо observable.ref
=> observable.shallow
, 99.9% мне нужно вглубь реактивный объект/массив т.к. всё равно все данные с сервера фетчатся и просто подменяются.
А так же остаётся запретить "autorun" на проекте и научить всех проектировать нормальное ООП
Как 2 пальца об асфальт
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
Ага. Но меня такое не останавливает) Уже с конца 16-ой версии Реакта никаких изменений. Использование внутреннего API даёт крутые возможности, его скорее сделают задокументированным чем удалят без предоставления альтернатив.
То же самое на Mobx. Сравните читабельность.
Мне больше всех нравятся минималистичные варианты типа Jotai, на работе пишу на Mobx, но для своих проектов использую личные разработки (например Remini), в какой-то момент становиться интереснее написать то что самому себе хочется, чем мириться с проблемами любого существующего стейт менеджера.
Адептам Mobx я противостоять не вижу смысла, как и сражаться с другими командами, делающими по-своему отличные решения, напротив мы все развиваем одну отрасль.
use-between же о другом, и лично я ищу тех кому будет интересно писать свой проект в стиле хуков! И сердечно предлагаю попробовать свежее решение.
я ищу тех кому будет интересно писать свой проект в стиле хуков!
Т.е. проекты сразу же обреченные быть write only и неподдерживаемыми спустя уже пол года разработки. Зашибись)
Мне больше всех нравятся минималистичные варианты типа Jotai,
Не используется getters/setters - смешно, на помойку. Максимально убогий интерфейс взаимодействия через setLala(newValue) нелепость.
но для своих проектов использую личные разработки (например Remini)
Такой же бесполезный хлам.
мириться с проблемами любого существующего стейт менеджера.
А может просто перестать считать проблемами, "проблемы" притянутые за уши и которые в реальной жизни ни на что не влияют и никак не ощущаются.
А вообще в чем сакральный смыл намеренно говнокодить и вообще писать лишний код?
Хм. Удивительно грубая речь. Думаю вопрос риторический. Могу немного перефразировать, следует вкладывать смысл во всё что мы пишем, а не только в код. Не писать глупостей и лишнего)
Думаю вопрос риторический
Ну не совсем. Использовать на проекте управление состоянием в виде хуков реакта, redux и прочей шелухи - это гарантированно запоротый write-only проект.
Единственный стейт менеджер для реакта который позволяет писать человеческий код это MobX. Т.к. там getters/setters, мутабильность, автоматическая подписка/отписка, 0% лишнего кода(не считая makeAutoObservable и observable, но любой уважающий себя разработчик и это не пишет, т.к. давно написал плагин/трансформер кода и все компоненты на этапе сборки заворачиваются в observable, а классы в которых нет вызова makeAutoObservable в конструкторе, превращаются в классы с этим вызовом) и другие приятности например функция when.
P.S. Я бы рад отвечать быстрее, но из-за всяких недалеких, обиженных жизнью, которые заминусовали карму из-за того, что мое мнение не сходится с их мнением, приходится писать не чаще 1 раза в час. Понятное дело что серой массе комфортно находится именно в обществе серой массы, но что тогда делать тем, кто мыслит глубже и дальше?
Жму руку. Приятно выйти на дружественную ноту!
Классно написал про MobX, я тоже писал свой плагин на babel, что бы автоматически оборачивать компоненты в observer) нашелся бы кто-нибудь кто в open source оформил бы такой, да что бы ещё работал на SWC, вообще б цены не было!
плагин на babel
Это и без бабеля можно, через допилку внутренностей Реакта.
Например, так сделано в signal (упрощенная копия mobx) - https://github.com/preactjs/signals/blob/main/packages/react/src/index.ts#L189
но любой уважающий себя разработчик и это не пишет, т.к. давно написал плагин/трансформер кода и ..
Уважающий себя, но не уважающий других. Я предпочитаю использовать по минимуму нестандартные плагины, т.к. любому новому разработчику придется вникать, почему у вас все это работает без обычных функций инициализации. И врядли вы прям уж так досконально пишите документацию к вашим плагинам. Добавить одну строчку в класс это не так страшно.
спасибо за статью, чуть ранее писал про удобное использование контекстов статью которая решает все эти проблемы.
В целом ваш способ позволяет пошарить состояние из кастомного хука. но это не решает ни как проблему не явно DI. так как с таким подходом может быть хук в хуке внутри которого хук. и вы заколебаетесь искать виновника который рендерит ваш компонент)
p.s сверху хейтеры у которых есть только redux/mobx и асинхронные сторы :)
у меня под статьёй так же насрали
Спасибо за добрые слова!)
Да. Есть такое дело, конечно “use-between” не защитит.
Современная бизнес ориентированная среда фронтенда продвигает идею, что не нужно решать проблем производительности до их появления. А архитекторы же напротив будут требовать закладывать как можно более надежный фундамент и контролировать код в течении всей его жизни с первых дней.
Реальный пример из жизни, я работал над большим проектом с redux, где повсеместно в компонентах использовался “useSelector”, мейнтейнер так беспокоился о производительности функций компонентов, что все вычисления вынес внутрь “useSelector”. А в итоге сработал обратый эффект, так как при изменении любого значения внутри стора даже самого незначительного запускались пересчёты всех “useSelector” из отображенных компонентов. В какой-то момент это стало заметно.
Для меня use-between это так же и уход от единого стора и возможность делить данные так, что бы пересчётов было как можно меньше. Что бы сторы были как можно проще и вообще я бы ввел ограничение на размер файла в один-два экрана для 95% случаев), что бы код было проще читать.
Грамотное использование React.memo, маленькие сторы, слежение за эффектами и как можно более “плоская” структура, так как чем больше вложений тем сложнее размотать потом код.
Хорошо что всё эти рекомендации применимы к Реакт приложению и без use-between!)
мейнтейнер так беспокоился о производительности функций компонентов, что все вычисления вынес внутрь “useSelector”. А в итоге сработал обратый эффект, так как при изменении любого значения внутри стора даже самого незначительного запускались пересчёты всех “useSelector” из отображенных компонентов. В какой-то момент это стало заметно.
Там палка о двух концах. С одной стороны, иногда полезно вычислять селектором, например, в массиве объектов проверить, есть ли объекты с некоторым свойством. Такой селектор возвращает true/false, и перерендер компонента будет далеко не так часто после изменения массива, как если бы мы просто заселектили массив и посчитали уже в компоненте. А с другой, если есть редко изменяемые данные, но по которым отрабатывают какие-нибудь числодробилки, то тут да, лишних вычислений будет много. Впрочем, этот последний пункт легко исправляется библиотекой reselect
Это уже не первая библиотека, которая прячет за "хуками" использование глобальной переменой спрятанной в самой библиотеке (`instances`). Примерно так же поступает бОльшая половина библиотек "убийц редакса" (я не поклонник редакса, просто отметил).
Вопрос из зала - как Вы это тестируете?
Шэрим стейт между хуками в React