Size: a a a

2020 July 08

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
иначе почему мы в редаксе верим людям на слово что они ничего не будут мутировать, надо же всё обмазать Object.freeze
источник

M

Maxim Ambrosevich in ☄️ effector
🚀🔬 🚀🔬🚀🔬
всплытие это нарушение инкапсуляции.
Почему? Если это евент, реакция которая ожидается вышестоящим компонентом?
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
Maxim Ambrosevich
Почему? Если это евент, реакция которая ожидается вышестоящим компонентом?
хорошо, что глобальное недопонимание мы разрешили, детали оставляю на самостоятельное изучение
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
настоятельно рекомендую забыть про попытки создавать сторы и эвенты внутри компонентов на этапе изучения, к этому вопросу всегда можно вернуться когда мы будем уверены что понимаем друг друга и принципы библиотеки
источник

R

Rafael 🦠 in ☄️ effector
От себя добавлю, что лучше начать с обработки ошибок в api слое 😑
источник

Б

Богдан in ☄️ effector
Maxim Ambrosevich
@ZeroBias мне эффектор как раз нравится за то, что он не централизованный. У меня есть идея сделать компоненты в реакте, у которых логика будет лежать отдельно и импортироваться в компоненты, создаваясь вместе с инстансом компонента. Основная причина в том, что иначе получаются огромные компоненты в которых все намешано, и это в добавок трудно переиспользовать. Мне показалось что эффектор прям как по маслу зайдет в такую концепцию, но я стокнулся с двумя вопросами: если у меня есть несколько инстансов одной и то же сущности, для каждой из которых я хотел бы иметь свой стор, то получается у меня есть вариант сделать только централизованный стор где я буду их держать? И второй - если все сторы создаются статически, то тогда у меня всегда в памяти лежат все сторы?

Возможно мои желания идут в разрез с концепцией эффектора?
Почему-то захотелось напомнить что простой нативный js уже предоставляет много удобных фич по работе с данными. Например
1) создаем стор
const appStore = {tasks: []};
2) при клике по кнопке добавляем новую задачу
const onClick = () => {
 appStore.tasks.push({text: "", completed: false, comments: []})
}
3) рендерим где-нибудь в компоненте
<div>
{appStore.tasks.map(task => <Task task={task}/>)}
</div>
4) компонент <Task/> получает через пропсы объект задачи и может например отрендерить вложенный список комментариев этой задачи (и также пушить новые комменты в обработчике нового коммента)
<div>
{task.comments.map(comment => <Comment comment={comment}/>}
</div>
5) и аналогично каждый компонент <Comment/> получив свой объект комментария может отрендерить список вложенных комментариев или чего-то еще
6) А если мы еще добавим обратную ссылку на родительский объект при создании то нам не нужно будет пробрасывать компоненту <Comment/> еще какие-то данные через пропсы (включая еще проброс через родительские компоненты) - он всегда сможет получить нужные данные самостоятельно обращаясь по обратным ссылкам comment.parent.parent.tasks..

Получается очень интересная ситуация что с одной стороны у нас есть единственный глобальный стор а с другой стороны каждый компонент будет работать со своим объектом как будто это локальное состояние (то есть не нужно выносить логику обработки из компонента куда-то в другое место и можно обновлять сам объект по месту в самом компоненте, например обновить текст в инпуте task.text = newValue)

Правда надо заметить что примеры выше пока еще не рабочие - у нас не происходит обновление компонентов так как при пуше в список или при изменении текста мы никак не сообщаем реакту чтобы он вызывал обновление компонентов. Это можно решить двумя способами
1) либо юзать стейт-менеджеры которые трекают какие данные с какими компонентами связаны (чтобы вызывать перендер только этих компонентов вместо всего приложения)
2) либо добавить функцию reconcile() и вызвать ее в конце каждого js-обработчика (это конечно +1 строчка но зато явно и никакой магии) внутри которой будет вызов перерендера всего приложения (перерендер не совсем правильное слово потому что там происходит просто дифф двух деревьев) - const reconcile = () =>  ReactDOM.render(<App/>, rootEl). Тут может показаться что выполнять дифф всего приложения если изменилось что-то в одном компоненте это медленно но в реальности тормоза появятся лишь на больших приложениях с >10к дом-элементов (и даже тогда можно просто добавить виртуальные списки)
источник

M

Maxim Ambrosevich in ☄️ effector
Богдан
Почему-то захотелось напомнить что простой нативный js уже предоставляет много удобных фич по работе с данными. Например
1) создаем стор
const appStore = {tasks: []};
2) при клике по кнопке добавляем новую задачу
const onClick = () => {
 appStore.tasks.push({text: "", completed: false, comments: []})
}
3) рендерим где-нибудь в компоненте
<div>
{appStore.tasks.map(task => <Task task={task}/>)}
</div>
4) компонент <Task/> получает через пропсы объект задачи и может например отрендерить вложенный список комментариев этой задачи (и также пушить новые комменты в обработчике нового коммента)
<div>
{task.comments.map(comment => <Comment comment={comment}/>}
</div>
5) и аналогично каждый компонент <Comment/> получив свой объект комментария может отрендерить список вложенных комментариев или чего-то еще
6) А если мы еще добавим обратную ссылку на родительский объект при создании то нам не нужно будет пробрасывать компоненту <Comment/> еще какие-то данные через пропсы (включая еще проброс через родительские компоненты) - он всегда сможет получить нужные данные самостоятельно обращаясь по обратным ссылкам comment.parent.parent.tasks..

Получается очень интересная ситуация что с одной стороны у нас есть единственный глобальный стор а с другой стороны каждый компонент будет работать со своим объектом как будто это локальное состояние (то есть не нужно выносить логику обработки из компонента куда-то в другое место и можно обновлять сам объект по месту в самом компоненте, например обновить текст в инпуте task.text = newValue)

Правда надо заметить что примеры выше пока еще не рабочие - у нас не происходит обновление компонентов так как при пуше в список или при изменении текста мы никак не сообщаем реакту чтобы он вызывал обновление компонентов. Это можно решить двумя способами
1) либо юзать стейт-менеджеры которые трекают какие данные с какими компонентами связаны (чтобы вызывать перендер только этих компонентов вместо всего приложения)
2) либо добавить функцию reconcile() и вызвать ее в конце каждого js-обработчика (это конечно +1 строчка но зато явно и никакой магии) внутри которой будет вызов перерендера всего приложения (перерендер не совсем правильное слово потому что там происходит просто дифф двух деревьев) - const reconcile = () =>  ReactDOM.render(<App/>, rootEl). Тут может показаться что выполнять дифф всего приложения если изменилось что-то в одном компоненте это медленно но в реальности тормоза появятся лишь на больших приложениях с >10к дом-элементов (и даже тогда можно просто добавить виртуальные списки)
Примерно это я сегодня и рассматривал( не совсем так в деталях, но похожее по сути), но злесь есть некоторая когнитивная сложность, подумал об эффекторе как о более понятном решении
источник

M

Maxim Ambrosevich in ☄️ effector
Сложность для понимания потом коллегами я имею ввиду
источник

R

Ruslan 🌀 in ☄️ effector
Telegram
⚙️ do in ☄️ effector
Представьте себе ванильный джаваскрипт... данные у вас хранятся в переменных (примитивы всякие, объекты), вы пишете императивный код (ифы, циклы, свичи), гоняете эти данные по функциям, создаёте новые переменные. Но вы не можете подписаться на переменные, на их изменения, не можете отследить поток данных между ними.

Допустим у вас есть объект с данными и методы, которые эти данные изменяют. Вы хотите создать интерфейс для пользователя, чтобы показать эти данные и дать возможность с ними взаимодействовать. Вы берете реакт, создаёте компонент на jsx и выводите там свои данные, на кнопки навешиваете методы, и рендерите компонент на странице. Но о ужас 😱, пользователь кликает на кнопки, данные в объекте меняются, но данные на странице не обновляются. Вам нужно просто перерендерить компонент, если данные изменились, но данные лежат в обычном джаваскрипт объекте, вы не можете на него подписаться, вы также не можете простым способом отследить вызовы ваших функций. Что же делать?

Используйте эффектор! Возьмите вместо…
источник

DS

Dmitriy Shuleshov in ☄️ effector
И не лень же вам стока букав писать....
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
Dmitriy Shuleshov
И не лень же вам стока букав писать....
у него это что-то вроде насморка
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
так как в дискуссии по поводу своей писанины он никогда не вступает, отстрелялся и ушёл, монолог; я делаю выводы
источник

DS

Dmitriy Shuleshov in ☄️ effector
Не пойму че дискутировать.
Если не чувствуешь потребность , то завел обьектик , положил на данные и дергаешь реакт.рендер на каждый апдейт. Жизнь удалась.

Хотя стоооп, это же уже было....
источник

Б

Богдан in ☄️ effector
🚀🔬 🚀🔬🚀🔬
так как в дискуссии по поводу своей писанины он никогда не вступает, отстрелялся и ушёл, монолог; я делаю выводы
Неправда, я обычно отвечаю, просто когда подобные обсуждения занимают больше часа то вспоминаешь что есть более важные дела, а постоянно переключаться между работой и телеграмом я не умею
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
Богдан
Неправда, я обычно отвечаю, просто когда подобные обсуждения занимают больше часа то вспоминаешь что есть более важные дела, а постоянно переключаться между работой и телеграмом я не умею
ну я так и сказал: высмаркиваешься и идёшь дальше
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
напоминаю что в прошлый раз дискуссия со стеной окончилась тем что на практике ты свои идеи так и не реализовал


https://t.me/effector_ru/133131
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
хотя конечно прогресс огромный — уже диалог, вау — , но по прежнему недостаточный чтобы начать воспринимать твои слова всерьёз, если кроме догадок и очередных великолепных озарений в них ничего нет
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
источник

🚀🚀

🚀🔬 🚀🔬🚀🔬... in ☄️ effector
нет практики — нет содержания в словах, идеальному миру твой стейт в глобалах подходит безупречно, но к сожалению в реальности будет ряд проблем до которых ты в режиме «отстрелялся и ливнул в закат» просто не имеешь возможности дойти
источник