React: кастомные события, иерархия и другое
- В Реакте можно создавать собственные события. На самом деле это просто коллбэки, которые мы передаем по цепочке:
- главный компонент передает через props функцию...
- ...а дочерние возвращают данные.
На одном из звеньев мы ловим классическое DOM-событие вроде onClick, и кастомное событие обрабатывается.
Концепция однонаправленных потоков типов данных очень важна для Реакта и будет рассмотрена позже (наверное).
- Компонент-функцию можно легко переделать в класс, если переместить её JSX вместе с return в метод render класса.
- В новом JS появился метод массива findIndex. Возвращает элемент массива, соответствующий условию. Вкусный сахар.
- В целом, в Реакт любое использование мутабельных методов - антипаттерн. В любом месте.
- Если поле State - массив, и задача - удалить элемент, решение может быть таким:
1. Получаем любым немутабельным методом первую часть - от начала до удаляемого индекса.
2. Примерно так же получаем остаток - от удаляемого + 1 элемента до конца.
3. Склеиваем.
4. Возвращаем новый массив в State.
#React
- В Реакте можно создавать собственные события. На самом деле это просто коллбэки, которые мы передаем по цепочке:
- главный компонент передает через props функцию...
- ...а дочерние возвращают данные.
На одном из звеньев мы ловим классическое DOM-событие вроде onClick, и кастомное событие обрабатывается.
Концепция однонаправленных потоков типов данных очень важна для Реакта и будет рассмотрена позже (наверное).
- Компонент-функцию можно легко переделать в класс, если переместить её JSX вместе с return в метод render класса.
- В новом JS появился метод массива findIndex. Возвращает элемент массива, соответствующий условию. Вкусный сахар.
- В целом, в Реакт любое использование мутабельных методов - антипаттерн. В любом месте.
- Если поле State - массив, и задача - удалить элемент, решение может быть таким:
1. Получаем любым немутабельным методом первую часть - от начала до удаляемого индекса.
2. Примерно так же получаем остаток - от удаляемого + 1 элемента до конца.
3. Склеиваем.
4. Возвращаем новый массив в State.
#React
Командная строка - grep:
Grep - поисковик по директориям и файлам. Ищет по строкам или регулярным выражениям.
Запрос выглядит, например, так:
$ grep something .file
Команда вернет все вхождения паттерна something в файле .file.
Греп принимает множество опций. Из них особо часто применяются опции контекста и рекурсивного обхода.
- Опции контекста:
-B, -A, -C
Они же
—before-context
—after-context
—context
В свою очередь, эти опции принимают числа. Они задают количество строк, которые консоль выведет до, после или по обе стороны от искомой строки.
- Опции обхода:
-R - опция рекурсивного обхода директорий со всеми поддиректориями. Полезно, если неизвестен файл для поиска, но известна директория.
-Rn - рекурсивно обойдет директории, а заодно укажет номер строки, где совпадение найдено.
Примеры:
$ grep -C 2 something .file
$ grep -R something directory
#bash
Grep - поисковик по директориям и файлам. Ищет по строкам или регулярным выражениям.
Запрос выглядит, например, так:
$ grep something .file
Команда вернет все вхождения паттерна something в файле .file.
Греп принимает множество опций. Из них особо часто применяются опции контекста и рекурсивного обхода.
- Опции контекста:
-B, -A, -C
Они же
—before-context
—after-context
—context
В свою очередь, эти опции принимают числа. Они задают количество строк, которые консоль выведет до, после или по обе стороны от искомой строки.
- Опции обхода:
-R - опция рекурсивного обхода директорий со всеми поддиректориями. Полезно, если неизвестен файл для поиска, но известна директория.
-Rn - рекурсивно обойдет директории, а заодно укажет номер строки, где совпадение найдено.
Примеры:
$ grep -C 2 something .file
$ grep -R something directory
#bash
Командная строка - Vim, Nano
...или как перестать бояться тупиков в Git и начать жить
- В редакторах Linux, в которые входит и Vim, используется навигация через CTRL + {key}. Например, CTRL + X закроет редактор.
- В подсказках CTRL обозначается как символ ^. Соответственно, Git сам объясняет, как выйти из редактора.
- Главное отличие Vim - у него есть разные режимы:
- режим команд (по-умолчанию)
- режим редактирования: войти - клавиша i, выйти - ESC или ^[
- Визуальный режим
- Режим командной строки.
- Как выйти из Vim?!!1 - вопрос миллионов.
Есть два основных выхода:
1. ^X
2. :q в режиме команд.
А выйти с сохранением можно через :wq.
#bash
...или как перестать бояться тупиков в Git и начать жить
- В редакторах Linux, в которые входит и Vim, используется навигация через CTRL + {key}. Например, CTRL + X закроет редактор.
- В подсказках CTRL обозначается как символ ^. Соответственно, Git сам объясняет, как выйти из редактора.
- Главное отличие Vim - у него есть разные режимы:
- режим команд (по-умолчанию)
- режим редактирования: войти - клавиша i, выйти - ESC или ^[
- Визуальный режим
- Режим командной строки.
- Как выйти из Vim?!!1 - вопрос миллионов.
Есть два основных выхода:
1. ^X
2. :q в режиме команд.
А выйти с сохранением можно через :wq.
#bash
Bash - управление потоками
Вывод программ можно не только выводить на экран, но и писать в файл. И наоборот. Делается это операторами:
< > >>
< - выводит на экран;
> - записывает в файл (с перезаписью)
>> - добавляет в существующий файл
Эти операции связаны с потоками ОС. Вот эти потоки:
STDIN (файловый дескриптор 0) (прием данных в процесс)
STDOUT (ф.д.1) (вывод данных из процесса)
STDERR (ф.д.2) (вывод ошибок)
Вывод ошибок отделен от обычного вывода для удобного их логгирования. Потоки можно перенаправлять друг в друга, но это не очень существенная информация для фронтенда.
Еще один, очень важный оператор для консольных команд - это пайп. Выглядит он как вертикальная черта: " | ".
Его задача - передавать данные из одной программы в другую на манер конвейера.
Пайп применяется, потому что, как и в NodeJS, UNIX придерживается принципа атомарности программ. Лучше соединить несколько grep пайпом, чем усложнять сам grep.
Пример:
$ grep hello | grep world // выведет все совпадения по hello и world
#bash
Вывод программ можно не только выводить на экран, но и писать в файл. И наоборот. Делается это операторами:
< > >>
< - выводит на экран;
> - записывает в файл (с перезаписью)
>> - добавляет в существующий файл
Эти операции связаны с потоками ОС. Вот эти потоки:
STDIN (файловый дескриптор 0) (прием данных в процесс)
STDOUT (ф.д.1) (вывод данных из процесса)
STDERR (ф.д.2) (вывод ошибок)
Вывод ошибок отделен от обычного вывода для удобного их логгирования. Потоки можно перенаправлять друг в друга, но это не очень существенная информация для фронтенда.
Еще один, очень важный оператор для консольных команд - это пайп. Выглядит он как вертикальная черта: " | ".
Его задача - передавать данные из одной программы в другую на манер конвейера.
Пайп применяется, потому что, как и в NodeJS, UNIX придерживается принципа атомарности программ. Лучше соединить несколько grep пайпом, чем усложнять сам grep.
Пример:
$ grep hello | grep world // выведет все совпадения по hello и world
#bash
Структуры данных: заметки
- Двухсвязный список может быть выгоднее массива: любые операции вставки и удаления занимают в нём время О(1). Но, в зависимости от данных, можно обойтись односвязным списком или просто массивом.
- Поиск в связанном списке равен О(n), если не прибегать к дополнительному индексированию и другим трюкам.
- Стек полезен, например, в линтинге. Каждый раз, когда создается открывающая скобка в коде, в стек редактора заносится единица, когда создается закрывающая - удаляется. Если на конец кода стек не пуст - то допущена ошибка.
- Реализовать стек можно с помощью массива или односвязного списка. Я делал и обычной строкой :)
- В деревьях есть понятие "листового узла" - это узлы, не имеющие потомков.
- Закономерность в деревьях: ребер в дереве всегда равно количеству узлов минус 1. Так получается, потому что к любому из узлов (кроме корня) ведет один указатель.
- Глубина узла дерева - это количество ребер, которое нужно пройти, чтобы добраться до узла. Например, у корня глубина - 0: на него ничего не указывает.
- Высота дерева - это количество ребер, которое нужно пройти от самого глубокого узла до корня.
- Свойства двоичного дерева:
1. Максимальное количество узлов на уровне высоты: 2^уровень.
2. Максимальное количество узлов дерева: (2^высота дерева)-1.
3. Высота дерева по количеству узлов: log2(n+1)-1
- Деревья бывают сбалансированными и несбалансированными. Сбалансированные деревья максимально заполнены. Это важно, потому что высота дерева прямо влияет на количество операций поиска по нему. Максимальная заполненность - это состояние, когда разница между правым и левым поддеревьями не меньше константного числа (обычно, 1).
- Хранить деревья в памяти можно по-разному:
1. Обычное дерево можно хранить в связанном списке.
2. Complete binary tree - дерево, в котором все узлы, кроме листовых, заполнены, и дерево расширяется слева - допустимо хранить в массиве.
#структуры_данных
- Двухсвязный список может быть выгоднее массива: любые операции вставки и удаления занимают в нём время О(1). Но, в зависимости от данных, можно обойтись односвязным списком или просто массивом.
- Поиск в связанном списке равен О(n), если не прибегать к дополнительному индексированию и другим трюкам.
- Стек полезен, например, в линтинге. Каждый раз, когда создается открывающая скобка в коде, в стек редактора заносится единица, когда создается закрывающая - удаляется. Если на конец кода стек не пуст - то допущена ошибка.
- Реализовать стек можно с помощью массива или односвязного списка. Я делал и обычной строкой :)
- В деревьях есть понятие "листового узла" - это узлы, не имеющие потомков.
- Закономерность в деревьях: ребер в дереве всегда равно количеству узлов минус 1. Так получается, потому что к любому из узлов (кроме корня) ведет один указатель.
- Глубина узла дерева - это количество ребер, которое нужно пройти, чтобы добраться до узла. Например, у корня глубина - 0: на него ничего не указывает.
- Высота дерева - это количество ребер, которое нужно пройти от самого глубокого узла до корня.
- Свойства двоичного дерева:
1. Максимальное количество узлов на уровне высоты: 2^уровень.
2. Максимальное количество узлов дерева: (2^высота дерева)-1.
3. Высота дерева по количеству узлов: log2(n+1)-1
- Деревья бывают сбалансированными и несбалансированными. Сбалансированные деревья максимально заполнены. Это важно, потому что высота дерева прямо влияет на количество операций поиска по нему. Максимальная заполненность - это состояние, когда разница между правым и левым поддеревьями не меньше константного числа (обычно, 1).
- Хранить деревья в памяти можно по-разному:
1. Обычное дерево можно хранить в связанном списке.
2. Complete binary tree - дерево, в котором все узлы, кроме листовых, заполнены, и дерево расширяется слева - допустимо хранить в массиве.
#структуры_данных
Мотивация. Как двигаться вперед.
Пост не в формате канала, но касается нашей профессии не меньше нюансов программирования.
Многим знакома ситуация, когда любимая работа превращается в рутину, сомнения связывают руки и ты не растешь, как раньше. В таком положении важно не отдаваться ситуации, а вовремя оглядеться и изменить обстановку - внутри, снаружи или все сразу. За полтора года в IT заметил вот что. Я развиваюсь как профессионал и личность, когда:
1. Побеждаю. Решил сложную задачу, освоил технологию, убедил руководителя внедрить её. Даже маленькая победа - источник личной силы. Чем больше смог, тем проще достинуть еще большего.
2. Работаю для людей. Когда код решает реальные задачи - он меняет мир. Когда код видят коллеги, говорят о нём, он меняет их. Я всегда в выигрыше: критика оттачивает, похвала - дает больше сил.
3. Наслаждаюсь процессом. Будущее непредсказуемо. Размышления, устарела ли технология и востребована ли профессия, - гадания на кофейной гуще. Можно без лишних эмоций анализировать, выбирать перспективные направления. А эмоции - оставить для программирования. Технологии воплощают мои идеи. Каждая строка кода приносит удовольствие, удовольствие дает силу. Это прекрасно.
Создать для себя такие условия не слишком сложно. Если не дается - дробим на подзадачи и осиливаем маленькими шажками. Чувство от наполовину выполеннной задачи, казавшейся еще вчера неодолимой, невозможно переоценить.
#мотивация
Пост не в формате канала, но касается нашей профессии не меньше нюансов программирования.
Многим знакома ситуация, когда любимая работа превращается в рутину, сомнения связывают руки и ты не растешь, как раньше. В таком положении важно не отдаваться ситуации, а вовремя оглядеться и изменить обстановку - внутри, снаружи или все сразу. За полтора года в IT заметил вот что. Я развиваюсь как профессионал и личность, когда:
1. Побеждаю. Решил сложную задачу, освоил технологию, убедил руководителя внедрить её. Даже маленькая победа - источник личной силы. Чем больше смог, тем проще достинуть еще большего.
2. Работаю для людей. Когда код решает реальные задачи - он меняет мир. Когда код видят коллеги, говорят о нём, он меняет их. Я всегда в выигрыше: критика оттачивает, похвала - дает больше сил.
3. Наслаждаюсь процессом. Будущее непредсказуемо. Размышления, устарела ли технология и востребована ли профессия, - гадания на кофейной гуще. Можно без лишних эмоций анализировать, выбирать перспективные направления. А эмоции - оставить для программирования. Технологии воплощают мои идеи. Каждая строка кода приносит удовольствие, удовольствие дает силу. Это прекрасно.
Создать для себя такие условия не слишком сложно. Если не дается - дробим на подзадачи и осиливаем маленькими шажками. Чувство от наполовину выполеннной задачи, казавшейся еще вчера неодолимой, невозможно переоценить.
#мотивация
React, заметки:
- React.Fragment - обертка для элементов, которая используется, когда нельзя использовать <div> - например, в списках и таблицах. Имеет коротку запись <> ... </> (пока поддерживается малым количеством инструментов, не рекомендуется).
- Жизненный цикл компонента в Реакт - это очередь событий, которые происходят с компонентом. Как и в WP, для этих событий есть хуки:
1. componentDidMount() - срабатывает, когда компонент отрендерен как ДОМ-объект.
2. componentDidUpdate() - срабатывает при обновлении состояния компонента. Используется, например, для получения данных по АПИ. Предпочтительно делать это в нём, а не в конструкторе.
3. componentWillUnmount - перед удалением ДОМ-элемента.
4. componentDidCatch() - ловит ошибку, под которую не подготовлен обработчик.
#React #жизненный_цикл
- React.Fragment - обертка для элементов, которая используется, когда нельзя использовать <div> - например, в списках и таблицах. Имеет коротку запись <> ... </> (пока поддерживается малым количеством инструментов, не рекомендуется).
- Жизненный цикл компонента в Реакт - это очередь событий, которые происходят с компонентом. Как и в WP, для этих событий есть хуки:
1. componentDidMount() - срабатывает, когда компонент отрендерен как ДОМ-объект.
2. componentDidUpdate() - срабатывает при обновлении состояния компонента. Используется, например, для получения данных по АПИ. Предпочтительно делать это в нём, а не в конструкторе.
3. componentWillUnmount - перед удалением ДОМ-элемента.
4. componentDidCatch() - ловит ошибку, под которую не подготовлен обработчик.
#React #жизненный_цикл
React: Error Boundaries
Реакт своеобразно обрабатывает ошибки UI: неправильное поведение хотя бы одного компонента рушит все приложение. Это похоже на 500-ю ошибку сервера. Обработчик формы написан неправильно, не указано никаких настроек дебага - и вы видите заглушку с ошибкой. Реакт и вовсе выводит на проде пустую страницу.
Такое поведение недружелюбно для пользователей. Значит, об ошибках нужно позаботиться заранее.
Что происходит с ошибкой в дереве компонентов? Она всплывает, пока не доберется до root. Error boundaries - это компоненты, в которые встроены обработчики ошибок, не дающие тем всплыть и уничтожить приложение. Для обработки используются метод жизненного цикла componentDiDCatch().
Простой пример: при ошибке обработчик выводит вместо пустой страницы - компонент-заглушку, который даст пользователю понять, что произошла ошибка.
ComponentDidCatch работает только для методов жизненного цикла и рендеринга приложения. Ошибки в event listener-ах или асинхронных коллбеках он не ловит.
#React #обработка_ошибок #UX
Реакт своеобразно обрабатывает ошибки UI: неправильное поведение хотя бы одного компонента рушит все приложение. Это похоже на 500-ю ошибку сервера. Обработчик формы написан неправильно, не указано никаких настроек дебага - и вы видите заглушку с ошибкой. Реакт и вовсе выводит на проде пустую страницу.
Такое поведение недружелюбно для пользователей. Значит, об ошибках нужно позаботиться заранее.
Что происходит с ошибкой в дереве компонентов? Она всплывает, пока не доберется до root. Error boundaries - это компоненты, в которые встроены обработчики ошибок, не дающие тем всплыть и уничтожить приложение. Для обработки используются метод жизненного цикла componentDiDCatch().
Простой пример: при ошибке обработчик выводит вместо пустой страницы - компонент-заглушку, который даст пользователю понять, что произошла ошибка.
ComponentDidCatch работает только для методов жизненного цикла и рендеринга приложения. Ошибки в event listener-ах или асинхронных коллбеках он не ловит.
#React #обработка_ошибок #UX
React: разделение ответственности
Философия Реакта - блочность, разделение, дробление. Компоненты не должны содержать свалку из сетевого кода, логики его обработки, обработки ошибок, рендеринга... Все эти возможности нужно разносить в отдельные классы, компоненты или функции. Разделяя ответственность и максимально абстрагируя код от данных, мы добиваемся таких выгод, как удобство переиспользования и удержания в голове логики приложения.
Error boundaries тоже могут быть отделены от компонентов, занятых рендерингом. Для этого можно использовать props.children. В этом свойстве объекта props находится код, который написан между открывающим и закрывающим тегами компонента:
<Header>
<ChildComponent />
</Header>
Для обработки ошибок создаем компонент-обертку, которая возвращает своих "детей":
<ErrorBoundry>
<Header />
</ErrorBoundry>.
#React #паттерны #обработка_ошибок
Философия Реакта - блочность, разделение, дробление. Компоненты не должны содержать свалку из сетевого кода, логики его обработки, обработки ошибок, рендеринга... Все эти возможности нужно разносить в отдельные классы, компоненты или функции. Разделяя ответственность и максимально абстрагируя код от данных, мы добиваемся таких выгод, как удобство переиспользования и удержания в голове логики приложения.
Error boundaries тоже могут быть отделены от компонентов, занятых рендерингом. Для этого можно использовать props.children. В этом свойстве объекта props находится код, который написан между открывающим и закрывающим тегами компонента:
<Header>
<ChildComponent />
</Header>
Для обработки ошибок создаем компонент-обертку, которая возвращает своих "детей":
<ErrorBoundry>
<Header />
</ErrorBoundry>.
#React #паттерны #обработка_ошибок
HTML: создаем звуки
Разберем работу со звуковыми файлами в HTML. Для этого есть семантический тег HTML5 - audio. Он заменяет устаревший flash простым, встроенным в HTML механизмом.
Тег предоставляет удобное API для работы через JS. Вот некоторые методы:
.play() - запуск проигрывания файла;
.pause() - понятно, зачем.
У тега есть и масса атрибутов, включая булевы, которые, естественно, можно цеплять в JS. Например, currentTime - текущее время воспроизведения. Его можно, например, обнулять при клике, чтобы каждый раз не дожидаться конца проигрывания.
#HTML5
Разберем работу со звуковыми файлами в HTML. Для этого есть семантический тег HTML5 - audio. Он заменяет устаревший flash простым, встроенным в HTML механизмом.
Тег предоставляет удобное API для работы через JS. Вот некоторые методы:
.play() - запуск проигрывания файла;
.pause() - понятно, зачем.
У тега есть и масса атрибутов, включая булевы, которые, естественно, можно цеплять в JS. Например, currentTime - текущее время воспроизведения. Его можно, например, обнулять при клике, чтобы каждый раз не дожидаться конца проигрывания.
#HTML5
Git: полезные мелочи
- git status -s выводит статус версий в сокращенном виде.
- git rm <file> ожидаемо удаляет файл из индексации и в целом из проекта. Если удалить файл другим способом, он останется в системе со статусом "changed, bit not updated". Команда принимает также регулярные выражения и паттерны путей.
- git rm -f <file> удаляет файл принудительно, даже после индексации.
- git rm --cached <file> позволит отключить отслеживание файла, сохранив его в папке проекта. Палочка-выручалочка, если что-то не внес в .gitignore.
- git mv <oldname> <newname> переименовывает файл, фактически удаляя и восстанавливая. Это поведение уже нам знакомо по unix-системам.
- git log --pretty с параметром fromat задает шаблон вывода лога. Новый формат задается строкой с параметрами вывода:
$ git log --pretty=format:"%h - %an, %ar : %s"
На JS эквивалент:
- git log (параметры pretty) —graph выводит историю ветвлений в виде графа - графической схемы. Наглядно и полезно для больших проектов.
#git #bash
- git status -s выводит статус версий в сокращенном виде.
- git rm <file> ожидаемо удаляет файл из индексации и в целом из проекта. Если удалить файл другим способом, он останется в системе со статусом "changed, bit not updated". Команда принимает также регулярные выражения и паттерны путей.
- git rm -f <file> удаляет файл принудительно, даже после индексации.
- git rm --cached <file> позволит отключить отслеживание файла, сохранив его в папке проекта. Палочка-выручалочка, если что-то не внес в .gitignore.
- git mv <oldname> <newname> переименовывает файл, фактически удаляя и восстанавливая. Это поведение уже нам знакомо по unix-системам.
- git log --pretty с параметром fromat задает шаблон вывода лога. Новый формат задается строкой с параметрами вывода:
$ git log --pretty=format:"%h - %an, %ar : %s"
На JS эквивалент:
`${cuttedHash} - ${nameOfCommitter}
`;- git log (параметры pretty) —graph выводит историю ветвлений в виде графа - графической схемы. Наглядно и полезно для больших проектов.
#git #bash
Хуки Реакта: что, зачем и как
Что:
Хуки - это новое АПИ для модных функциональных пацанов (с), которое позволяет отказаться от компонентов-классов. Преимуществом классов была возможность использовать локальное состояние, но с хуками добавлять state можно и в функциональны компоненты. Не путать с хуками жизненного цикла!
Зачем:
1. Переиспользуемость. В классических компонентах для разделения состояния использовали, например, компоненты-обертки. С хуками все проще: пишем логику функциями в отдельном файле, импортируем, вызываем. Всё.
2. Простота. Официальный туториал утверждает: для Реакт-разработчков сложно усвоить правила работы this в JS. Мои соболезнования компаниям, где работают такие девелоперы. Тем не менее, возня с привязкой this сократилась с упрощенной до отсутствующей.
Как:
Все просто. Создаем через деструктуризацию пользовательнкую переменную и метод обновления:
...И применяем, как ранее в классах. О тонкостях, типа useEffect, позже.
Логика, написанная через хуки, полностью независима при каждом вызове. Поэтому useState может быть использована даже в пределах одного компонента.
#React #хуки
Что:
Хуки - это новое АПИ для модных функциональных пацанов (с), которое позволяет отказаться от компонентов-классов. Преимуществом классов была возможность использовать локальное состояние, но с хуками добавлять state можно и в функциональны компоненты. Не путать с хуками жизненного цикла!
Зачем:
1. Переиспользуемость. В классических компонентах для разделения состояния использовали, например, компоненты-обертки. С хуками все проще: пишем логику функциями в отдельном файле, импортируем, вызываем. Всё.
2. Простота. Официальный туториал утверждает: для Реакт-разработчков сложно усвоить правила работы this в JS. Мои соболезнования компаниям, где работают такие девелоперы. Тем не менее, возня с привязкой this сократилась с упрощенной до отсутствующей.
Как:
Все просто. Создаем через деструктуризацию пользовательнкую переменную и метод обновления:
const [age, setAge] = useState(42);
...И применяем, как ранее в классах. О тонкостях, типа useEffect, позже.
Логика, написанная через хуки, полностью независима при каждом вызове. Поэтому useState может быть использована даже в пределах одного компонента.
#React #хуки
Хуки Реакта-2: useEffect
Герой заголовка -
Собственно эффект - это функция, которую и цепляет на себя хук.
Хук эффекта объединяет возможности методов жизненного цикла:
Для того, чтобы выполнять очистку и другие похожие действия, в компонентах-классах привязанные к
useEffect автоматически выполняются для каждого обновления. Сделали так для того, чтобы избежать ошибок с отсутствием прописанной логики обновления компонента.
Однако такое поведение может замедлить приложение. Чтобы отключить его, нужно передать хуку вторым аргументом массив со значением, которое может измениться при обновлении:
useEffect можно использовать многократно в одном компоненте. Это позволит, например, разбить эффекты на те, что должны выполняться всегда, и те, что выполняются только при изменении значения.
#React #хуки
Герой заголовка -
useEffect
- так называемый хук эффекта. Под эффектом понимают действия, которые в компонентах-классах выполняются в методах жизненного цикла. Собственно эффект - это функция, которую и цепляет на себя хук.
Хук эффекта объединяет возможности методов жизненного цикла:
componentDidMount, componentDidUpdate, componentWillUnount
. Это поможет объединить похожую логику, разбитую в классах по методам жизненного цикла. Для того, чтобы выполнять очистку и другие похожие действия, в компонентах-классах привязанные к
componentWillUnount
, хук useEffect должен возвращать функцию: она будет вызвана на этом этапе жизненного цикла.useEffect автоматически выполняются для каждого обновления. Сделали так для того, чтобы избежать ошибок с отсутствием прописанной логики обновления компонента.
Однако такое поведение может замедлить приложение. Чтобы отключить его, нужно передать хуку вторым аргументом массив со значением, которое может измениться при обновлении:
useEffect(() => {
document.title = `Вы нажали ${count} раз
`;}, [count]);
В этом случае эффект будет вызван, только если значение count изменится.useEffect можно использовать многократно в одном компоненте. Это позволит, например, разбить эффекты на те, что должны выполняться всегда, и те, что выполняются только при изменении значения.
#React #хуки
Проект Houdini: типизация кастомных переменных
CSS-препроцессоры упрощают жизнь разработчика, в числе прочего, удобными переменными. Не так давно эта фича вошла в стандарт:
(нативная CSS-переменная в глобальной области видимости)
Однако не обошлось без ложки дегтя. Обычные, вшитые в стандарт значения CSS обладают
Проект Houdini - новое API, предоставляющее доступ ко всем стадиям обработки браузером кода - предлагает решение. Из JS мы сможем регистрировать типы переменных:
Теперь переменная --my-color принимает только значения цветов. Считывая тип, движок может выполнять больше действий с переменной - включая анимации.
В миру эта часть проекта Houdini называется CSS Properties and Values API. К сожалению, проект страдает от избыточной сложности и слабой поддержки браузерами. В будущем он поможет строить архитектуру веб-приложений гибче и оптимизированнее, ну а пока - просто достоин внимания.
#CSS #Houdini
CSS-препроцессоры упрощают жизнь разработчика, в числе прочего, удобными переменными. Не так давно эта фича вошла в стандарт:
root: {
--my-color: #fff;
}
(нативная CSS-переменная в глобальной области видимости)
Однако не обошлось без ложки дегтя. Обычные, вшитые в стандарт значения CSS обладают
типами
, на которые браузер опирается, выполняя анимации. В кастомных переменных типов нет. Проект Houdini - новое API, предоставляющее доступ ко всем стадиям обработки браузером кода - предлагает решение. Из JS мы сможем регистрировать типы переменных:
CSS.registerProperty({
name: "--my-color",
syntax: "<color>",
initialValue: "black"
});
Теперь переменная --my-color принимает только значения цветов. Считывая тип, движок может выполнять больше действий с переменной - включая анимации.
В миру эта часть проекта Houdini называется CSS Properties and Values API. К сожалению, проект страдает от избыточной сложности и слабой поддержки браузерами. В будущем он поможет строить архитектуру веб-приложений гибче и оптимизированнее, ну а пока - просто достоин внимания.
#CSS #Houdini
Тонкости let и const
- Хотя константе нельзя присвоить новое значение, само это значение менять можно:
- Дважды объявить через let переменную с одинаковым именем в одной области видимости нельзя, а в разных - можно:
- Существует феномен
Любопытно, что обращение к let-переменной в более высокой области видимости до её инициализации с операцией typeof выведет undefined.
- При объявлении в глобальной области видимости var становится свойством глобального объекта window. Это небезопасное поведение изменили в ES6: let и const не связаны с глобальным объектом.
#JS
- Хотя константе нельзя присвоить новое значение, само это значение менять можно:
const x = [2,4,5];
x[0] = 6;
// массив в константе x изменится на [6, 4 ,5]- Дважды объявить через let переменную с одинаковым именем в одной области видимости нельзя, а в разных - можно:
let x = 10;
const z = () => {
let x = 20;
console.log(x)
}
z()
// выведет 20- Существует феномен
Temporal Dead Zone
- "временная мёртвая зона", появляющаяся, когда поток входит в лексическую область видимости, содержащую переменную, но еще не доходит до неё. Попытка обратиться к переменной в мёртвой зоне вызовет ошибку - в отличие от var, которая поднимается в самое начало блока и выводит undefined, если обратиться к ней до привязки.const x = () => {
console.log(typeof z);
let z = 10;
}
x()
// выбросит ошибкуЛюбопытно, что обращение к let-переменной в более высокой области видимости до её инициализации с операцией typeof выведет undefined.
- При объявлении в глобальной области видимости var становится свойством глобального объекта window. Это небезопасное поведение изменили в ES6: let и const не связаны с глобальным объектом.
#JS
Английский язык: слова и грамматика
- to expand (гл.): расширять.
- warm-up (сущ.) - разминка.
- tense: время. Не путать с time: tense - концепция грамматики.
- expresses: выражает, высказывает.
Simple tenses имеют общий принцип: simple present говорит о чем-либо повторяющемся, постоянном, past и fututre - о конкретном, единственном случае.
Пример
"Pavel makes holywars about frameworks every day" - "каждый день Павел (обычно, постоянно, как правило) разжигает холивары про фреймворки".
А вот
"I'll make delicious jQuery pasta for you tomorrow, sweetheart" (завтра я приготовлю тебе аппетитную лапшичку на жиквреи, милая).
#english
- to expand (гл.): расширять.
- warm-up (сущ.) - разминка.
- tense: время. Не путать с time: tense - концепция грамматики.
- expresses: выражает, высказывает.
Simple tenses имеют общий принцип: simple present говорит о чем-либо повторяющемся, постоянном, past и fututre - о конкретном, единственном случае.
Пример
simple present
:"Pavel makes holywars about frameworks every day" - "каждый день Павел (обычно, постоянно, как правило) разжигает холивары про фреймворки".
А вот
simple future
:"I'll make delicious jQuery pasta for you tomorrow, sweetheart" (завтра я приготовлю тебе аппетитную лапшичку на жиквреи, милая).
#english
Интернет-маркетинг: UTM-метки
UTM-метки - удобный инструмент аналитики трафика. Они прописываются в URI и состоят из пар ключ-значение:
Пример остроумного применения: в уличные билборды вшивали QR-код с UTM-метками, где каждый борд нес уникальную метку. На их основе составляли аналитику - и сокращали расходы на неэффективные стенды.
Другой пример. Google Analytics воспринимает трафик из приложений как прямые заходы. UTM-метки отмечают этот трафик, и аналитик получает верную картину.
UTM-метки должны располагаться до "якоря" (#).
#аналитика #utm
UTM-метки - удобный инструмент аналитики трафика. Они прописываются в URI и состоят из пар ключ-значение:
utm_source=google
Ключей бывает всего пять:utm_параметр
. Значения могут быть произвольными и либо прописываются руками (в конструкторе URL), либо генерируются на стороне рекламной кампании.Пример остроумного применения: в уличные билборды вшивали QR-код с UTM-метками, где каждый борд нес уникальную метку. На их основе составляли аналитику - и сокращали расходы на неэффективные стенды.
Другой пример. Google Analytics воспринимает трафик из приложений как прямые заходы. UTM-метки отмечают этот трафик, и аналитик получает верную картину.
UTM-метки должны располагаться до "якоря" (#).
#аналитика #utm
Плагины Wordpress: лучшие практики
- Префиксы. Чтобы не было конфликтов имен, добавляем префикс - например, в виде названия плагина - везде, куда только можем.
- Проверяем наличие переменных, функций, классов и т.д. Используем if ( isset( $variable )) {}.
- Определяем переменные по возможности внутри функций.
- Правильно группируем файлы. В папке плагина в идеале должны быть два файла - plugin.php, uninstall.php. Остальное раскладывается по папкам languages, includes, admin->js,css,images (админка), public->js,css,images (фронт).
- Код, используемый в админке и во фронтенде, разделяем. Используем if ( is_admin() ) {}
- Префиксы. Чтобы не было конфликтов имен, добавляем префикс - например, в виде названия плагина - везде, куда только можем.
- Проверяем наличие переменных, функций, классов и т.д. Используем if ( isset( $variable )) {}.
- Определяем переменные по возможности внутри функций.
- Правильно группируем файлы. В папке плагина в идеале должны быть два файла - plugin.php, uninstall.php. Остальное раскладывается по папкам languages, includes, admin->js,css,images (админка), public->js,css,images (фронт).
- Код, используемый в админке и во фронтенде, разделяем. Используем if ( is_admin() ) {}
SQL, манипуляция данными. Часть 1.
БД можно представить трехмерной фигурой из двухмерных слоев-таблиц, наподобие листов Excel. Сами слои состоят из ячеек. В ячейках - числа или строки.
SQL - язык гибкого взаимодействия с этой фигурой.
Пример простых взаимодействий с БД - выборка данных (SELECT) и вставка (INSERT). К слову, капслок в операторах - не более чем условность для простоты разделения операторов и оперндов. Сам я её соблюдаю, но и в lowercase все работает.
Сейчас рассмотрим выборку.
#SQL
БД можно представить трехмерной фигурой из двухмерных слоев-таблиц, наподобие листов Excel. Сами слои состоят из ячеек. В ячейках - числа или строки.
SQL - язык гибкого взаимодействия с этой фигурой.
Пример простых взаимодействий с БД - выборка данных (SELECT) и вставка (INSERT). К слову, капслок в операторах - не более чем условность для простоты разделения операторов и оперндов. Сам я её соблюдаю, но и в lowercase все работает.
Сейчас рассмотрим выборку.
#SQL