Начинаем наше погружение в работу фронтенд-библиотек и фреймворков. И даже если вы занимались только бэкендом и мир JavaScript вам казался страшным, то самое время расширить кругозор и заглянуть на его сотрону. Как хороший дизайнер должен представлять, можно ли нарисованную им страницу сверстать, так и хорошему бэкендеру было бы неплохо понимать, что от вас хотят фронтендеры. Да и помимо кругозора там можно подсмотреть многие паттерны, которые для вас могут оказаться полезными.
Так что начнём наше исследование на примере написания с нуля браузерного приложения. И сегодня с классического серверного рендеринга HTML-страниц перейдём на построение DOM-дерева через JavaScript. Заодно рассмотрим пользу отделения данных от представления. Выделим побочные эффекты и сделаем удобные и тестируемые чистые функции:
А в следующем эпизоде в нашей свёрстанной странице добавим динамику. Чтобы данные подгружались по API и в реальном времени обновлялись цены через WebSocket.
Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Простой урок, но при этом полезная тема про распаковку структур. Очень ждал что-нибудь про React или vue
Спасибо!
Спасибо.
Отличный материал, давно задавался вопросом от чего отталкиваться при работе с фронтендом, и очень помогла проведённая аналогия бекендом. Спасибо!
За временнЫе метки - респект!
Спасибо, очень интересно!
Возник вопрос, почему в современном js так любят использовать const вместо переменных? Разве это не противоречит самой сути констант?
Вместо
var
теперь рекомендуется использоватьlet
для переопределяемых значений иconst
для привязанных навсегда.Константу
const a=5
илиconst b={amount:3}
нельзя позже переопределить на новое значениеa=6
илиb={amount:7}
. В константе будет постоянно храниться указатель на первоначальный объект. Но на сам объект при этом никакое ограничение не накладывается, поэтому можно поменять любое его поле напрямую черезb.amount=7
.Это противоречит сути констант из классических компилируемых языков, в которых константе можно присвоить только скалярное значение и потом компилятор везде в код подставляет напрямую это значение вместо константы.
В JS в константу можно присвоить что угодно. Даже изменяемый объект. Поэтому и получаем, что константа по сути остаётся константой, храня неизменяемую ссылку на объект, но сам этот объект можно модифицировать.
Дмитрий, спасибо за ответ!
Супер. Очень доходчиво
Материал на высшем уровне!
Спасибо, очень интересно! Если использовать history api то получается если взять к примеру вк. Левая часть (меню) статическая, а правая динамическая. Это получается на сервере возвращается json и на основе этого рендерится новостная лента список друзей мета информация страницы и тд?
Таким образом при воспроизведении музыки спокойно можно кликать на разные вкладки меню без перезагрузки страницы? Если вместо json фрагмент html отправить site.local/api/news это будет не быстрее чем на клиенте рендерить?
Да, все фронтенд-приложения Single Page Application (SPA) используют History API вместо реальной смены адреса с переоткрытием страницы. То есть навешиваются на onCLick всех ссылок и просто меняют адрес. И в зависимости от текущего пути уже выводят разные компоненты внутри шаблона. Например, у нас мы можем внутри 'App' под вызовом
Header()
вызывать некую функцию вроде:в которую передавать
window.location.pathname
. Она будет работать как маршрутизатор и в итоге на странице будет заменяться только контент.И каждый компонент-страница вроде
Lots
уже будет запрашивать нужный ему JSON по API.Браузеру почти нет разницы, откуда он всё берёт. Хоть с HTML, хоть из JS. Всё равно он сначала парсит тэги из HTML в дерево элементов и только после этого их рендерит.
Как раз в следующем эпизоде мы добавим динамическую загрузку и подгрузку данных. И там увидим, что основное неудобство будет не в первой загрузке данных, а в последующем обновлении. И там уже на JavaScript будет удобнее манипулировать элементами.
Спасибо. Хорошо излагаете.
Отличный материал. Но несколько "НО":
А так все по делу
Как всегда спасибо, и есть вопрос, я посмотрел пока только 6 уроков, но вижу что react даже с JSX сложен для восприятия и главное для редактирования простым верстальщиком который знает html+css, посмотрел на vue и он вроде проще для визуального восприятия и изменения верстки, вопрос почему вы выбрали React и чем он лучше Vue, спасибо!
Они идут от разных сторон. React из JS, а Vue из HTML.
React использует нативный JS с
React.createElement
. И просто через примитивный JSX позволяет заменять вызовReact.createElement
на HTML-подобный синтаксис.А Vue изначально имеет полноценный отдельный HTML-шаблонизатор с
<template>
, куда уже нужно вписывать нужные ему управляющие конструкции вродеv-if
иv-for
.Верно. React с JSX удобнее и привычнее JS-программисту, но меньше понятен HTML-верстальщику.
А Vue своим HTML-шаблонизатором
<template>
удобен верстальщику, но неудобен программисту.Спасибо за ответ, все как всегда подробно и понятно!
Отлично материал подается! Сам я бэкендер, но чтобы не дергать фронтовиков по мелочам и понимать, что там происходит, стараюсь быть в теме клиентской стороны. Спасибо автору, все по делу и очень понятно.
Спасибо за урок! Есть немного обратной связи:
Названия функций должны быть глаголом. Дано понятие "Компонент", но не сказано, что это такое и почему функции с большой буквы. Зная твой подход, я то конечно подозреваю, что далее ты к этому подведешь и станет понятно. :)
Зависимостей между функциями лучше же тоже избегать, даже если они чистые?
Сокращать синтакис объявления объекта мне кажется лишним и ошибочным. Не знаю почему разработчики пошли по этому пути! :)
Первый вариант мне кажется более читаемым.
Компонент в React можно сделать в виде функции или в виде класса. Поэтому удобно их всегда именовать по смыслу существительным Header вместо названия-глагола renderHeader для функции и Header для класса. Ещё такое особое именование компонентов-виджетов удобно, чтобы не путать их с другими обычными функциями-глаголами.
Избегать стоит только прямых зависимостей от "грязных" функций, чтобы их можно было подменять в тестах на чистые заглушки. А используемые чистые функции тестированию никак не мешают.
Да, некоторым более читаемо классическое многословное написание:
вместо нового короткого аналога:
Синтаксический сахар практически всегда придумывается для укорачивания кода. Со временем он становится привычным.
Спасибо за как всегда блестящую подачу материала, Дмитрий! Просмотрел весь цикл до конца и вернулся в начало, чтобы переосмыслить увиденное. И неожиданно для себя обнаружил несколько однотипных тавтологий и мест, которые можно было бы упростить. Я по поводу деструктуризации. Она теряет смысл, когда в объявлении функции и при её вызове используется один объект. Таких примеров здесь несколько, например
и потом в вызовах
Здесь достаточно простого синтаксиса
а затем
В вызовах других методов, например, в Clock внутри App() не нужна такая подстановка аргументов, как
Вместо этого можно было просто написать
поскольку функция Clock объявлена с оператором деструктуризации как
И таких примеров тоже несколько.
Сейчас многие функции-компоненты принимают только один аргумент. Пока мы вызываем функции вручную мы можем передавать его просто без деструктуризации.
Но вскоре мы перейдём на JSON-формат описания виртуального дерева и синтаксис JSX. Там мы со всеми компонентами будем работать уже универсально атоматически, а не вручную. И там будет удобнее передавать один объект
props
, чтобы не путаться в числе параметров и их порядке.Именно для этого мы сейчас все функции-компоненты написали одинаково с деструктуризацией из одного параметра, чтобы потом нам было возможно это универсально автоматизировать.
Интересно получается
Или войти через: