Огромное спасибо за столь полезный контент: продвинутые темы на реакте с такими подробными пояснениями помогают углубить свои знания и многократно повысить скилл.
Александр, спасибо за доклад. Сам использую memo на проекте довольно-таки часто (стараюсь с умом, в некоторых случаях с функциями сравнения). Получилось структурировано все, с примерами и выводами. Так держать!
@@it-sin9k нет, наоборот !) Я видел про файбер , но подумал что это кто-то другой. Ps: хороший канал , очень нравится , но когда ты капаешься в исходниках , я перестаю понимать и становится менее интересно ( но это только мое мнение) )
Про скобочки я так думаю , что они не просто из не откуда , а это результат вызова createElement , в исходниках там всегда новый объект , а то я на секунду подумал , что именно из-за мемо они
25:50 тут на самом деле нужен всегда баланс: 1. не всегда еще на один уровень вверх есть смысл поднимать. Иногда получается лапша, которую потом читать нереально, где через 4-5 компонентов кто-то что-то пробрасывает 2. это не спасает от рендеров "нового" родителя. если в приложении просто иметь 0 мемо, то привет фул-рендер всего-всего на каждый чих тепер когда вижу "тяжелый" компонент с парой пропсов - он всегда уходит в мемо
спасибо тебе за доклад, про simple memo не знал забавно по defaultProps, я помню как пришел в компанию и спорил с крутаном, что defaultProps -- это ужасное решение, которое ломает мозги, потом что ты описываешь в типах пропсы как обязательные, а в итоге он их магически делает опциональными (тем что указал defaultProps), так же я доказывал что это deprecated способ и есть es6, зачем нам плясать с бубном, я был не один, а с еще одним парнем и мы его еле убедили, жаль что я не знал про simple memo, было бы проще :D но эт было в начале 2020)
Если в кратце - старайтесь не использовать memo, если изменении структуры приложения не позволяет исключить не желательные ререндеры и экономит 1 из 10 рендеров, тогда используй memo.
26:41 Мне казалось, что все, что ниже родителя в дереве (все, что есть в render/return), обновляется при изменении пропсов/стейта. А получается, что children не обновляются да и вообще не рендерятся в родителе. Т.е. они типа только в родителе родителя рендерятся (где они определяются в виде jsx или данных) и подаются по одной и той же ссылке (при условии, что родитель родителя не перерендеривается)? Т.е. для меня нагляднее первый вариант, с соседями, но зато вариант с children выявил пробелы в знаниях.
Еще вопрос. На 25:03. Смысл оборачивать компонент ExpansiveTree если у него нету пропсов? В таком случае при каких условиях он не будет рендерится? Shallow equal / compare? Пропсов то нету. Спасибо)
memo спасает от рендеров родителя. React устроен так, что если родитель зарендерился, то и все его дети тоже зарендеряться, даже если ты не передаешь props вообще никаких. Единственный вариант предотвратить это - использовать memo
24:50 я посмотрел по перфомансу: memo в данном случае быстрее чем первый метод решения от Дэна Абрамова(обернуть инпут с состоянием в отдельный компонент). что скажете на этот счёт?
Как раз недавно начали новый плейлист посвященный теме Redux. Во вторник новое видео выйдет) Думаю в одном из будущих видео, поделюсь своими мыслями и на эту тему тоже
90% я думаю эта цифра завышенная цифра. Логика обычно простая: если данные пере используемые между экранами, то храни в Redux, если нет, то храни в state. В моих проектах это примерно 60% - 70% локальных данных
попробуй протестировать это у себя) Идея в том, что он создает новый объект с предыдущими данными, а не точно тот же объект возвращает. В итоге children всегда новый
Касательно хаков по мимо (27минута). А если компонент получает пропсы от родителя? Мы уже не сможем вынести этот компонент отдельно и юзать его как соседний, а не внутренний, если я понятно выразился. Ответь плз при возможности на вопросы, я буду очень благодарен. Я работаю реакт разработчиком, для меня развитие - очень важно) спасибо заранее
Спасибо за вопросы) обязательно на все отвечу) В каждой ситуации нужно по разному разбивать компоненты и думать как лучше их разбить. Конечно не всегда получается разбить красиво, в таком случае проще использовать React.memo и не париться
@@it-sin9k Спасибо большое за твой контент, извини за то что отвлекаю тебя, хотел бы узнать твое мнение, может просто напишешь копаю ли я в ту сторону или куда копать, а может я просто тупой и fiber уже давно никто не использует и придумали какую нибудь лучшую замену. У себя в видео ты говорил, что React создает при рендере новое дерево (это ведь дерево которое реакт конструирует из узолов называемых fiber?), я читал статью (Max Koretskyi Inside Fiber), в ней он тоже говорил, что реакт создает дерево из узлов fiber, но там он так же упоминал, что узел fiber не создается при кажом рендере снова, а изменяются (но тогда получается, что не остается work in progress Tree --- то есть не с чем провети сравнине) --- (это по сути бред, то, что я описал, просто, я подумал, что ты в видео про согласование опирался на его статью) {вопрос по сути в том прибегает ли react к созданию новых узлов fiber при каких либо обстоятельствах} Еще один, как react пропускает элементы при выполнении рендара? Он делает определенную проверку? Например: при запуске setState от useState, (происходит определенная запись в соответствующий объект fiber с пометкой о том, что нужно выполнить работу, и react бежит по дереву и когда доходит до это пометки он вызывает функцию, которую берет из поля объекта узла fiber, где она записана в поле type), у меня сложилось такое впечатление, что react не может вернуть при вызове самой верхней функции-компонента один связанный результат(дерево) (потому что после вызова createElement от функции-компонента нет никакой ссылки в полученном объекте о возвращенном результате ---- следовательно он где то уже зафиксирован) (поэтому, возможно, если следовать моему воображению, когда react начинает вызов нижестоящих функций-компонент (все транспилируется в вызовы craateElement и там), react автоматически создает для каждого узла fiber клон и в него записывает всю новую информацию о каждом элементе, а потом уже сверяет с новым деревом currentTree ) - это просто мое предположение чуть-чуть основанное на информации, которую я где то обрывками находил (её не много) (я просто не понимаю как react собирает информацию об объектах, если в компоненте если ее вывести совсем нет информации, а если вывести результат вызова createElement от внутреннего контейнера, то то там она уже будет, то есть return от компонента контейнера всегда возвращает пустой объект)
В общем потратил я какое то время чтобы найти прувы к моим обрывочным знаниям. Идея в том, что все файбер ноды хранятся не деревом, а условно массивом. И когда обходится дерево, указатель на элемент в массиве меняется. Или элементы могут удаляться в середине массива. Таким образом делая workInProgress дерева все что нужно это по указателю достать fiber ноду и доработать ее или заменить на другую. Чтобы подтвердить мои слова, вот отрывок из этой статьи: indepth.dev/posts/1008/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react React processes updates very quickly and to achieve that level of performance it employs a few interesting techniques. One of them is building a linear list of fiber nodes with effects for quick iteration. Iterating the linear list is much faster than a tree, and there’s no need to spend time on nodes without side-effects. А так же вот исходники React, где добавляются элементы в массив и удаляются function push(cursor, value, fiber) { index++; valueStack[index] = cursor.current; { fiberStack[index] = fiber; } cursor.current = value; } function pop(cursor, fiber) { if (index < 0) { { error('Unexpected pop.'); } return; } { if (fiber !== fiberStack[index]) { error('Unexpected Fiber popped.'); } } cursor.current = valueStack[index]; valueStack[index] = null; { fiberStack[index] = null; } index--; }
Обьясните пожалуйста, может я чего то не понимаю. Simplememocomponent проверяет классовый компонент или функциональный. Так React.memo используется только для функциональных. Для классовых есть purecomponent. Почему compare почти никогда не используются? А если пропсы вложенные? Имею ввиду если мы пропсом передаем вложенный обьект? Такие пропсы не так уж и редко используются
С помощью memo можно обернуть что угодно, как функциональный компонент так и классовый. Просто те кто в React давно, раньше только и использовать PureComponent поэтому даже в голове не стоит вопрос, зачем классовый компонент в memo оборачивать, но физически это возможно. В моих проектах compare почти никто и не передает. Чаще всего либо передается только нужная часть объекта для этого компонента, либо мемоизируется объект. Видимо у вас другой опыт. Было бы интересно увидеть какие функции compare вы используете на проекте
@@it-sin9k спасибо большое. Удивлен что так быстро ответили на мои вопросы. Приятно) Посоветую ваш канал и своим знакомым фронтент разработчикам) Иногда, чтобы не передавать слишком много пропсов, я бывает группирую необходимые данные в обьект и передаю их одним пропсом. В таком случае при мемо, shallowequal на такой пропс уже работать не будет тк он вложенный. Тут я использую функцию от библиотеки underscore (isEqual). И теперь я задаюсь вопросом Это нормальная практика? Плюс: передаю меньше пропсов компоненту. Минус: при мемо shallowequal работать не будет тк пропс вложенный
Чаще всего мы передаем не одним пропсом, а многими, и тогда оно нормально сравнивает без isEqual. Особенно если бывают глубокие объекты, это уже не очень рационально использовать isEqual
@@it-sin9k я не использую больше одного уровня вложенности. Это нормальная практика? Все, больше вопросов не задаю. И так перебрал) Еще раз, большое спасибо)
я отвечу так, я работал в многих компаниях и проектах. И обычно никто не группировал пропсы в один объект, чтобы передать их ниже. Просто передавали несколько props. Плохо ли это, хз. Скорее не обычно, и вопрос, который хочется задать, это какую пользу из этого можно извлечь?
Не совсем, react forget это компайлер. Который добавит, то чего не хватает или возможно удалит лишнее. Я планирую через пару видео, про него тоже рассказать, то как я это понял)
Очень классно! Просто топ!
Спасибо ты большой молодец!
Спасибо за уроки! Многие даже не понимают, что в видео автора подается информация уровня платных продвинутых курсов, а тут все бесплатно
Делюсь всем, что имею :)
Огромное спасибо за столь полезный контент: продвинутые темы на реакте с такими подробными пояснениями помогают углубить свои знания и многократно повысить скилл.
Спасибо что смотрите) это мотивирует создавать новый контент :)
Лучший доклад и канал! Спасибо! 👍
Спасибо!)
Спасибо, Александр!
У вас хорошо получается, рассказывать интересно о сложном и важном.
Спасибо :)
Очень круто!👍👍👍
Спасибо за твой труд!) Полезно посмотреть твои видосы, а тут целый доклад💪
Спасибо!
Очень сильно благодарю тебя за переданный опыт. Я считаю ты делаешь и объясняешь очень популярно.спасибо
Спасибо! Такие комментарии мотивируют продолжать вести канал)
Коммент для продвижения. Спасибо за годный контент.
Топ контент! Большое спасибо Александр!
Супер. Отличный доклад.
Должно быть больше просмотров.
Спасибо за ваш просмотр)
Дякую за відео, чотко і по полочках
Огонь, спасибо!
Спасибо за отличный полезный материал!
Александр, спасибо за доклад.
Сам использую memo на проекте довольно-таки часто (стараюсь с умом, в некоторых случаях с функциями сравнения). Получилось структурировано все, с примерами и выводами. Так держать!
Круто ! Освежил память, спасибо !
Да, да, да, как всегда, полезно, очень даже полезно, Саня респект, Синяку 100 лайков))
уже почти 100 лайков есть, спасибо!)
Супер!
Спасибо за отличный материал!
Спасибо!
Спасибо за содержательный доклад!
Спасибо!) Делитесь с коллегами :)
Супер контент, видео очень полезное, спасибо
спасибо! подача отличная
Ооо ) Наконец-то увидели АйтиСиняка вживую ) .
Надеюсь не разочаровал!)
И кстати, это уже второй мой доклад на канале) Можно было и раньше меня найти)
@@it-sin9k нет, наоборот !) Я видел про файбер , но подумал что это кто-то другой. Ps: хороший канал , очень нравится , но когда ты капаешься в исходниках , я перестаю понимать и становится менее интересно ( но это только мое мнение) )
Спасибо за фидбек) постараюсь держать грань между долгим ковырянием исходников и другим контентом)
Про скобочки я так думаю , что они не просто из не откуда , а это результат вызова createElement , в исходниках там всегда новый объект , а то я на секунду подумал , что именно из-за мемо они
Лютый топ!
Спасибо! Очень приятно)
Я обалдел от контента)
Совсем скоро выйдет еще один доклад с моим участием :)
Лайк еще до просмотра!
Топчик
25:50
тут на самом деле нужен всегда баланс:
1. не всегда еще на один уровень вверх есть смысл поднимать. Иногда получается лапша, которую потом читать нереально, где через 4-5 компонентов кто-то что-то пробрасывает
2. это не спасает от рендеров "нового" родителя. если в приложении просто иметь 0 мемо, то привет фул-рендер всего-всего на каждый чих
тепер когда вижу "тяжелый" компонент с парой пропсов - он всегда уходит в мемо
согласен со всеми пунктами :)
перед сном контентик подъехал )
Под такое думаю хорошо засыпать)
очень, thx!
Всегда пожалуйста :)
спасибо тебе за доклад, про simple memo не знал
забавно по defaultProps, я помню как пришел в компанию и спорил с крутаном, что defaultProps -- это ужасное решение, которое ломает мозги, потом что ты описываешь в типах пропсы как обязательные, а в итоге он их магически делает опциональными (тем что указал defaultProps), так же я доказывал что это deprecated способ и есть es6, зачем нам плясать с бубном, я был не один, а с еще одним парнем и мы его еле убедили, жаль что я не знал про simple memo, было бы проще :D но эт было в начале 2020)
Ох уж эти рабочие холивары) но я рад, что вам удалось убедить!
Если в кратце - старайтесь не использовать memo, если изменении структуры приложения не позволяет исключить не желательные ререндеры и экономит 1 из 10 рендеров, тогда используй memo.
26:41 Мне казалось, что все, что ниже родителя в дереве (все, что есть в render/return), обновляется при изменении пропсов/стейта. А получается, что children не обновляются да и вообще не рендерятся в родителе. Т.е. они типа только в родителе родителя рендерятся (где они определяются в виде jsx или данных) и подаются по одной и той же ссылке (при условии, что родитель родителя не перерендеривается)?
Т.е. для меня нагляднее первый вариант, с соседями, но зато вариант с children выявил пробелы в знаниях.
Возможно поможет понять "почему так", если вспомнить что children это просто одно из пропсов.
Еще вопрос. На 25:03. Смысл оборачивать компонент ExpansiveTree если у него нету пропсов? В таком случае при каких условиях он не будет рендерится? Shallow equal / compare? Пропсов то нету. Спасибо)
memo спасает от рендеров родителя. React устроен так, что если родитель зарендерился, то и все его дети тоже зарендеряться, даже если ты не передаешь props вообще никаких. Единственный вариант предотвратить это - использовать memo
зачем мне это знать)
24:50 я посмотрел по перфомансу: memo в данном случае быстрее чем первый метод решения от Дэна Абрамова(обернуть инпут с состоянием в отдельный компонент). что скажете на этот счёт?
Я скажу присылайте ссылку с кодом :). Заявление звучит многообещающим!
@@it-sin9k простите. мне бы внимательным быть не помешало). с memo - 1.2ms, методом Абрамова - 0.5ms
p.s. действительно многообещающе
@@whicencer8819 бывает)
разница кстати существенная, больше чем в 2 раза!
супер! Есть просьба: объяснить на примерах что класть в Redux/MobX/etc., а что нет
Как раз недавно начали новый плейлист посвященный теме Redux. Во вторник новое видео выйдет) Думаю в одном из будущих видео, поделюсь своими мыслями и на эту тему тоже
@@it-sin9k спасибо, а то Абрамов говорит ,что в 90% случаев условный Redux не нужен, а народ (я тоже) реально не понимает как это и пихает всё в...😬
90% я думаю эта цифра завышенная цифра. Логика обычно простая: если данные пере используемые между экранами, то храни в Redux, если нет, то храни в state. В моих проектах это примерно 60% - 70% локальных данных
А можно скачать где-то презентацию?
Да, залил на github. Запустить надо с помощью shower
github.com/Sin9k/conference-react-memo
33:17 не очень понятно почему MemoChild возвращает новую ссылку, он же мемоизирвоан и должен возвращать одну и тоже ссылку каждый раз
попробуй протестировать это у себя) Идея в том, что он создает новый объект с предыдущими данными, а не точно тот же объект возвращает. В итоге children всегда новый
@@it-sin9k я протестировал) я думал Идея memo возвращать идентичный компонент ссылку, а теперь я подзадумался)
Касательно хаков по мимо (27минута). А если компонент получает пропсы от родителя? Мы уже не сможем вынести этот компонент отдельно и юзать его как соседний, а не внутренний, если я понятно выразился. Ответь плз при возможности на вопросы, я буду очень благодарен. Я работаю реакт разработчиком, для меня развитие - очень важно) спасибо заранее
Спасибо за вопросы) обязательно на все отвечу)
В каждой ситуации нужно по разному разбивать компоненты и думать как лучше их разбить. Конечно не всегда получается разбить красиво, в таком случае проще использовать React.memo и не париться
А получается на 32:47 memo все таки вернет закешированный результат просто обернутый в новый объект?
Верно!
@@it-sin9k Спасибо большое за твой контент, извини за то что отвлекаю тебя, хотел бы узнать твое мнение, может просто напишешь копаю ли я в ту сторону или куда копать, а может я просто тупой и fiber уже давно никто не использует и придумали какую нибудь лучшую замену.
У себя в видео ты говорил, что React создает при рендере новое дерево (это ведь дерево которое реакт конструирует из узолов называемых fiber?), я читал статью (Max Koretskyi Inside Fiber), в ней он тоже говорил, что реакт создает дерево из узлов fiber, но там он так же упоминал, что узел fiber не создается при кажом рендере снова, а изменяются (но тогда получается, что не остается work in progress Tree --- то есть не с чем провети сравнине) --- (это по сути бред, то, что я описал, просто, я подумал, что ты в видео про согласование опирался на его статью)
{вопрос по сути в том прибегает ли react к созданию новых узлов fiber при каких либо обстоятельствах}
Еще один, как react пропускает элементы при выполнении рендара?
Он делает определенную проверку?
Например:
при запуске setState от useState, (происходит определенная запись в соответствующий объект fiber с пометкой о том, что нужно выполнить работу, и react бежит по дереву и когда доходит до это пометки он вызывает функцию, которую берет из поля объекта узла fiber, где она записана в поле type),
у меня сложилось такое впечатление, что react не может вернуть при вызове самой верхней функции-компонента один связанный результат(дерево) (потому что после вызова createElement от функции-компонента нет никакой ссылки в полученном объекте о возвращенном результате ---- следовательно он где то уже зафиксирован)
(поэтому, возможно, если следовать моему воображению, когда react начинает вызов нижестоящих функций-компонент (все транспилируется в вызовы craateElement и там), react автоматически создает для каждого узла fiber клон и в него записывает всю новую информацию о каждом элементе, а потом уже сверяет с новым деревом currentTree ) - это просто мое предположение чуть-чуть основанное на информации, которую я где то обрывками находил (её не много)
(я просто не понимаю как react собирает информацию об объектах, если в компоненте если ее вывести совсем нет информации, а если вывести результат вызова createElement от внутреннего контейнера, то то там она уже будет, то есть return от компонента контейнера всегда возвращает пустой объект)
В общем потратил я какое то время чтобы найти прувы к моим обрывочным знаниям. Идея в том, что все файбер ноды хранятся не деревом, а условно массивом. И когда обходится дерево, указатель на элемент в массиве меняется. Или элементы могут удаляться в середине массива. Таким образом делая workInProgress дерева все что нужно это по указателю достать fiber ноду и доработать ее или заменить на другую. Чтобы подтвердить мои слова, вот отрывок из этой статьи:
indepth.dev/posts/1008/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react
React processes updates very quickly and to achieve that level of performance it employs a few interesting techniques. One of them is building a linear list of fiber nodes with effects for quick iteration. Iterating the linear list is much faster than a tree, and there’s no need to spend time on nodes without side-effects.
А так же вот исходники React, где добавляются элементы в массив и удаляются
function push(cursor, value, fiber) {
index++;
valueStack[index] = cursor.current;
{
fiberStack[index] = fiber;
}
cursor.current = value;
}
function pop(cursor, fiber) {
if (index < 0) {
{
error('Unexpected pop.');
}
return;
}
{
if (fiber !== fiberStack[index]) {
error('Unexpected Fiber popped.');
}
}
cursor.current = valueStack[index];
valueStack[index] = null;
{
fiberStack[index] = null;
}
index--;
}
Обьясните пожалуйста, может я чего то не понимаю. Simplememocomponent проверяет классовый компонент или функциональный. Так React.memo используется только для функциональных. Для классовых есть purecomponent.
Почему compare почти никогда не используются? А если пропсы вложенные? Имею ввиду если мы пропсом передаем вложенный обьект? Такие пропсы не так уж и редко используются
С помощью memo можно обернуть что угодно, как функциональный компонент так и классовый. Просто те кто в React давно, раньше только и использовать PureComponent поэтому даже в голове не стоит вопрос, зачем классовый компонент в memo оборачивать, но физически это возможно.
В моих проектах compare почти никто и не передает. Чаще всего либо передается только нужная часть объекта для этого компонента, либо мемоизируется объект. Видимо у вас другой опыт. Было бы интересно увидеть какие функции compare вы используете на проекте
@@it-sin9k спасибо большое. Удивлен что так быстро ответили на мои вопросы. Приятно)
Посоветую ваш канал и своим знакомым фронтент разработчикам)
Иногда, чтобы не передавать слишком много пропсов, я бывает группирую необходимые данные в обьект и передаю их одним пропсом. В таком случае при мемо, shallowequal на такой пропс уже работать не будет тк он вложенный. Тут я использую функцию от библиотеки underscore (isEqual). И теперь я задаюсь вопросом
Это нормальная практика? Плюс: передаю меньше пропсов компоненту. Минус: при мемо shallowequal работать не будет тк пропс вложенный
Чаще всего мы передаем не одним пропсом, а многими, и тогда оно нормально сравнивает без isEqual. Особенно если бывают глубокие объекты, это уже не очень рационально использовать isEqual
@@it-sin9k я не использую больше одного уровня вложенности. Это нормальная практика? Все, больше вопросов не задаю. И так перебрал)
Еще раз, большое спасибо)
я отвечу так, я работал в многих компаниях и проектах. И обычно никто не группировал пропсы в один объект, чтобы передать их ниже. Просто передавали несколько props. Плохо ли это, хз. Скорее не обычно, и вопрос, который хочется задать, это какую пользу из этого можно извлечь?
в итоге в новом реакте все будет мемо по дефолту?)
нет) не будет) они занимаются совсем другими проектами, судя по тому что они анонсировали на React Conf 2021 :)
@@it-sin9k так а react forget разве не про это?
ua-cam.com/video/lGEMwh32soc/v-deo.html
Не совсем, react forget это компайлер. Который добавит, то чего не хватает или возможно удалит лишнее. Я планирую через пару видео, про него тоже рассказать, то как я это понял)
Спасибо большое.
Добро пожаловать на канал :)