Компоненты высшего порядка
Компонента высшего порядка (High order component, HOC) - это паттерн для выделения повторяющейся логики и ее переиспользования. По сути это не компонент, а функция, которая возвращает компонент.
Компоненты высшего порядка не являются частью React, поэтому стандартов для их оформления нет. Но обычно эти функции принимают компонент А, добавляют к нему некоторую логику и возвращают уже новый компонент B, но который выводит внутри себя компонент A. При этом компонент B обычно не влияет на UI, то есть он только добавляет некоторую логику, но выводит тот же компонент А. В общем, это по сути декоратор.
Статья из документации (рус.): https://ru.reactjs.org/docs/higher-order-components.html
С налета понять может быть довольно сложно, поэтому лучше рассмотреть на примере простого логгера.
https://codepen.io/furrycat/pen/GRWGMOG?editors=0010
Функция Logger принимает любой другой компонент, который нужно обернуть, а затем создает компонент-обертку. Обертка не рендерит ничего лишнего, только добавляет некоторую логику - в данном случае логирует пропсы.
Если нужно, в оберточном компоненте можно объявить методы жизненного цикла, а также передать в функцию какой-нибудь конфигурационный объект.
Что тут нужно учитывать:
- HOC не должен ничего менять в том компоненте, который он оборачивает. Это должна быть чистая функция.
- HOC должен передать оборачиваемому компоненту все пропсы, так как он является промежуточным звеном и не должен ничего ломать. Для этого обычно используется синтаксис расширения (ссылка)
- HOC должен создаваться ВНЕ render-метода. Иначе при каждом рендере будет создаваться НОВЫЙ компонент, а значит, React не сможет ничего оптимизировать. Лучше всего получать HOC заранее, вне методов жизненного цикла.
- Если вы назначили компоненту высшего порядка атрибу ref, он не передастся оборачиваемому компоненту. (Решить эту проблему можно с помощью перенаправления рефов, которое мы разберем чуть позже)
#началоработы #примерыкода #hoc #паттерны #документация
Компонента высшего порядка (High order component, HOC) - это паттерн для выделения повторяющейся логики и ее переиспользования. По сути это не компонент, а функция, которая возвращает компонент.
Компоненты высшего порядка не являются частью React, поэтому стандартов для их оформления нет. Но обычно эти функции принимают компонент А, добавляют к нему некоторую логику и возвращают уже новый компонент B, но который выводит внутри себя компонент A. При этом компонент B обычно не влияет на UI, то есть он только добавляет некоторую логику, но выводит тот же компонент А. В общем, это по сути декоратор.
Статья из документации (рус.): https://ru.reactjs.org/docs/higher-order-components.html
С налета понять может быть довольно сложно, поэтому лучше рассмотреть на примере простого логгера.
https://codepen.io/furrycat/pen/GRWGMOG?editors=0010
Функция Logger принимает любой другой компонент, который нужно обернуть, а затем создает компонент-обертку. Обертка не рендерит ничего лишнего, только добавляет некоторую логику - в данном случае логирует пропсы.
Если нужно, в оберточном компоненте можно объявить методы жизненного цикла, а также передать в функцию какой-нибудь конфигурационный объект.
Что тут нужно учитывать:
- HOC не должен ничего менять в том компоненте, который он оборачивает. Это должна быть чистая функция.
- HOC должен передать оборачиваемому компоненту все пропсы, так как он является промежуточным звеном и не должен ничего ломать. Для этого обычно используется синтаксис расширения (ссылка)
- HOC должен создаваться ВНЕ render-метода. Иначе при каждом рендере будет создаваться НОВЫЙ компонент, а значит, React не сможет ничего оптимизировать. Лучше всего получать HOC заранее, вне методов жизненного цикла.
- Если вы назначили компоненту высшего порядка атрибу ref, он не передастся оборачиваемому компоненту. (Решить эту проблему можно с помощью перенаправления рефов, которое мы разберем чуть позже)
#началоработы #примерыкода #hoc #паттерны #документация
ru.legacy.reactjs.org
Компоненты высшего порядка – React
JavaScript-библиотека для создания пользовательских интерфейсов
Перенаправление рефов
Рефы в React позволяют получить прямую ссылку на DOM-элемент или экземпляр классового компонента. Иногда этой функциональности недостаточно.
- Например, у вас есть компонент TextInput, который рендерит поле ввода. И вы хотите из родительского компонента управлять фокусом этого поля. Но если вы установите реф на TextInput, он будет указывать именно на экземпляр компонента, а не на инпут внутри него. Перенаправление рефов позволяет пробросить реф от компонента к элементу/компоненту, который он рендерит.
https://codepen.io/furrycat/pen/NWpLwNm?editors=0010
Ref ведет себя не так, как обычные пропсы. Он привязывается к элементу, для которого указан, поэтому нам нужен метод React.forwardRef. Этот метод принимает рендер-функцию, в которую передает props и ref. Внутри рендер-функции можно вывести любую разметку и разместить ref там, где необходимо.
В некотором смысле React.forwardRef - это обертка/декоратор для функционального компонента, который добавляет в рендер-функцию второй аргумент (реф). То есть у нас есть способ привязывать рефы к функциональным компонентам.
Пошаговый алгоритм:
1. Компонент TextInput создан с помощью метода React.forwardRef. При рендеринге он получит ref и поместит его на DOM-элемент input.
2. В компоненте MyComponent создаем реф с помощью метода React.createRef и помещаем ее на TextInput.
3. В итоге в рефе оказывается ссылка на инпут.
Примечание: Реф внутри React.forwardRef, разумеется, можно привязать не только к DOM-элементу, но и к экземпляру классового компонента (как и всегда).
Важно: Не злоупотребляйте рефами. Это слишком сильно привязывает логику к DOM.
#рефы #примерыкода #документация
Рефы в React позволяют получить прямую ссылку на DOM-элемент или экземпляр классового компонента. Иногда этой функциональности недостаточно.
- Например, у вас есть компонент TextInput, который рендерит поле ввода. И вы хотите из родительского компонента управлять фокусом этого поля. Но если вы установите реф на TextInput, он будет указывать именно на экземпляр компонента, а не на инпут внутри него. Перенаправление рефов позволяет пробросить реф от компонента к элементу/компоненту, который он рендерит.
https://codepen.io/furrycat/pen/NWpLwNm?editors=0010
Ref ведет себя не так, как обычные пропсы. Он привязывается к элементу, для которого указан, поэтому нам нужен метод React.forwardRef. Этот метод принимает рендер-функцию, в которую передает props и ref. Внутри рендер-функции можно вывести любую разметку и разместить ref там, где необходимо.
В некотором смысле React.forwardRef - это обертка/декоратор для функционального компонента, который добавляет в рендер-функцию второй аргумент (реф). То есть у нас есть способ привязывать рефы к функциональным компонентам.
Пошаговый алгоритм:
1. Компонент TextInput создан с помощью метода React.forwardRef. При рендеринге он получит ref и поместит его на DOM-элемент input.
2. В компоненте MyComponent создаем реф с помощью метода React.createRef и помещаем ее на TextInput.
3. В итоге в рефе оказывается ссылка на инпут.
Примечание: Реф внутри React.forwardRef, разумеется, можно привязать не только к DOM-элементу, но и к экземпляру классового компонента (как и всегда).
Важно: Не злоупотребляйте рефами. Это слишком сильно привязывает логику к DOM.
#рефы #примерыкода #документация
Telegram
React Junior
Рефы
Реф - это прямая ссылка на компонент или на DOM-элемент. Обычно рефы используются для прямого управления DOM-элементами. React обычно не одобряет такой подход, но в некоторых ситуациях он оправдан:
- Управление фокусом, выделение текста или воспроизведение…
Реф - это прямая ссылка на компонент или на DOM-элемент. Обычно рефы используются для прямого управления DOM-элементами. React обычно не одобряет такой подход, но в некоторых ситуациях он оправдан:
- Управление фокусом, выделение текста или воспроизведение…
Рефы
Важно: До тех пор пока реф не передан в атрибут ref, он представляет собой обычный объект, который можно передавать как простой проп.
#рефы #важно #документация
Важно: До тех пор пока реф не передан в атрибут ref, он представляет собой обычный объект, который можно передавать как простой проп.
#рефы #важно #документация
Перенаправление рефов. Продолжение
Метод React.forwardRef передает в рендер-функцию ref вторым аргументом. И мы не обязаны сразу же привязывать этот реф к чему-нибудь внутри этой рендер-функции. На самом деле этот реф можно передать как обычный пропс какому-нибудь классовому компоненту, то есть записать не в атрибут ref компонента, а например в атрибут forwardedRef (название может быть любым). Таким образом реф можно пробросить на уровень вниз и использовать по назначению уже внутри классового компонента.
Такой подход применяется в компонентах высшего порядка.
Ведь если ваш компонент создан с помощью HOC и вы привязываете к нему ref, то этот реф будет указывать именно на компонент высшего порядка. Это неправильное поведение, так как HOC не должен влиять на интерфейс и ломать ссылки. Значит, здесь нам необходимо перенапраправление рефов.
Вместо того, чтобы из функции-обертки вернуть новый классовый компонент-обертку, нужно вернуть компонент, созданный с помощью метода React.forwardRef.
#документация #рефы
Метод React.forwardRef передает в рендер-функцию ref вторым аргументом. И мы не обязаны сразу же привязывать этот реф к чему-нибудь внутри этой рендер-функции. На самом деле этот реф можно передать как обычный пропс какому-нибудь классовому компоненту, то есть записать не в атрибут ref компонента, а например в атрибут forwardedRef (название может быть любым). Таким образом реф можно пробросить на уровень вниз и использовать по назначению уже внутри классового компонента.
Такой подход применяется в компонентах высшего порядка.
Ведь если ваш компонент создан с помощью HOC и вы привязываете к нему ref, то этот реф будет указывать именно на компонент высшего порядка. Это неправильное поведение, так как HOC не должен влиять на интерфейс и ломать ссылки. Значит, здесь нам необходимо перенапраправление рефов.
Вместо того, чтобы из функции-обертки вернуть новый классовый компонент-обертку, нужно вернуть компонент, созданный с помощью метода React.forwardRef.
#документация #рефы
Альтернатива перенаправлению рефов
Ссылка на пример с описанием: https://gist.github.com/gaearon/1a018a023347fe1c2476073330cc5509
Этот подход использует возможность передавать реф как пропс по дереву компонентов.
Минус этого подхода: требуется отдельный кастомный проп, о котором знают все заинтересованные компоненты. В то время как перенаправление рефов работает с встроенным свойством библиотеки React.
#документация #рефы #примерыкода
Ссылка на пример с описанием: https://gist.github.com/gaearon/1a018a023347fe1c2476073330cc5509
Этот подход использует возможность передавать реф как пропс по дереву компонентов.
Минус этого подхода: требуется отдельный кастомный проп, о котором знают все заинтересованные компоненты. В то время как перенаправление рефов работает с встроенным свойством библиотеки React.
#документация #рефы #примерыкода
Gist
dom_ref_forwarding_alternatives_before_16.3.md
GitHub Gist: instantly share code, notes, and snippets.
Рендер-пропсы
Значениями рендер-пропсов являются функции. Но эти функции используются не обычным образом (например, для обработки событий), а для рендера.
В рендер-пропе в компонент передается функция. Компонент вызывает ее в нужном месте своей разметки, передавая ей при необходимости аргументы. Функция выполняется и возвращает фрагмент JSX.
По сути это почти то же самое, что и props.children - дочерние элементы компонента. Кстати, проп children можно указывать явно, и он тоже может быть функцией, то есть рендер-пропом.
Статья из документации (рус.): https://ru.reactjs.org/docs/render-props.html
#рендерпропсы #jsx #документация
Значениями рендер-пропсов являются функции. Но эти функции используются не обычным образом (например, для обработки событий), а для рендера.
В рендер-пропе в компонент передается функция. Компонент вызывает ее в нужном месте своей разметки, передавая ей при необходимости аргументы. Функция выполняется и возвращает фрагмент JSX.
По сути это почти то же самое, что и props.children - дочерние элементы компонента. Кстати, проп children можно указывать явно, и он тоже может быть функцией, то есть рендер-пропом.
Статья из документации (рус.): https://ru.reactjs.org/docs/render-props.html
#рендерпропсы #jsx #документация
ru.legacy.reactjs.org
Рендер-пропсы – React
JavaScript-библиотека для создания пользовательских интерфейсов
Предохранители
Предохранители в React - это компоненты, которые могут отловить ошибки, произошедшие в жизненном цикле ниже лежащих (дочерних) компонентов, и вывести запасной UI (например, сообщение об ошибке). В результате этого целое приложение продолжает работать, даже если одна его часть упала с ошибкой.
Предохранители способны поймать ошибку только в СИНХРОННОМ JavaScript-коде НИЖЕЛЕЖАЩИХ компонентов (по отношению к самому предохранителю). Это значит, что они не смогут поймать ошибки в:
- асинхронном коде (setTimeout, обработчики событий, ajax-запросы)
- самом компоненте-предохранителе
- серверном рендеринге (SSR)
Чтобы компонент стал предохранителем, он должен реализовать один из следующих методов:
- статический метод getDerivatedStateFromError()
- метод экземпляра componentDidCatch()
Отсюда следует, что предохранителем может быть только классовый компонент. Оба метода будут подробнее разобраны в следующих постах.
По сути, предохранители - это декларативный аналог try-catch для компонентов.
Пример использования предохранителей из документации: https://codepen.io/gaearon/pen/wqvxGa?editors=0010
Важно: Начиная с React 16, ошибки, не отловленные ни одним из предохранителей, будут приводить к размонтированию всего дерева компонентов React. Команда проекта считает, что бОльшим злом будет вывести некорректный UI, чем удалить его целиком.
#документация #предохранители #обработкаошибок
Предохранители в React - это компоненты, которые могут отловить ошибки, произошедшие в жизненном цикле ниже лежащих (дочерних) компонентов, и вывести запасной UI (например, сообщение об ошибке). В результате этого целое приложение продолжает работать, даже если одна его часть упала с ошибкой.
Предохранители способны поймать ошибку только в СИНХРОННОМ JavaScript-коде НИЖЕЛЕЖАЩИХ компонентов (по отношению к самому предохранителю). Это значит, что они не смогут поймать ошибки в:
- асинхронном коде (setTimeout, обработчики событий, ajax-запросы)
- самом компоненте-предохранителе
- серверном рендеринге (SSR)
Чтобы компонент стал предохранителем, он должен реализовать один из следующих методов:
- статический метод getDerivatedStateFromError()
- метод экземпляра componentDidCatch()
Отсюда следует, что предохранителем может быть только классовый компонент. Оба метода будут подробнее разобраны в следующих постах.
По сути, предохранители - это декларативный аналог try-catch для компонентов.
Пример использования предохранителей из документации: https://codepen.io/gaearon/pen/wqvxGa?editors=0010
Важно: Начиная с React 16, ошибки, не отловленные ни одним из предохранителей, будут приводить к размонтированию всего дерева компонентов React. Команда проекта считает, что бОльшим злом будет вывести некорректный UI, чем удалить его целиком.
#документация #предохранители #обработкаошибок
static getDerivedStateFromError
Статический метод компонента-предохранителя. Вызывается после возникновения ошибки в каком-либо дочернем компоненте.
Входные параметры
👉 error - объект перехваченной ошибки
Выходные параметры
👉 Метод должен возвращать значение для обновления состояния компонента.
Особенности работы
👉 Метод вызывается во время этапа "рендера", поэтому в нем нельзя вызывать побочные эффекты.
Типичные случаи использования
👍 Изменение состояния для рендера запасного интерфейса (сообщение об ошибке).
👎 Для выполнения побочных эффектов следует использовать метод экземпляра componentDidCatch().
#компоненты #жизненныйциклкомпонента #документация
Статический метод компонента-предохранителя. Вызывается после возникновения ошибки в каком-либо дочернем компоненте.
Входные параметры
👉 error - объект перехваченной ошибки
Выходные параметры
👉 Метод должен возвращать значение для обновления состояния компонента.
Особенности работы
👉 Метод вызывается во время этапа "рендера", поэтому в нем нельзя вызывать побочные эффекты.
Типичные случаи использования
👍 Изменение состояния для рендера запасного интерфейса (сообщение об ошибке).
👎 Для выполнения побочных эффектов следует использовать метод экземпляра componentDidCatch().
#компоненты #жизненныйциклкомпонента #документация
componentDidCatch
Метод компонента-предохранителя. Вызывается после возникновения ошибки в каком-либо дочернем компоненте.
Входные параметры
👉 error - объект перехваченной ошибки
👉 info - объект с информацией о компоненте, в котором произошла ошибка
Особенности работы
👉 Метод вызывается во время этапа фиксации, поэтому внутри него можно вызывать побочные эффекты.
👉 В дев-режиме ошибки (даже обработанные методом componentDidCatch) всплывают наверх до объекта window. Поэтому можно их перехватывать с помощью обработчика window.onerror. На продакшене этого не происходит, обработанные ошибки дальше не всплывают.
Типичные случаи использования
👍 Логирование ошибок.
👎 Для изменения состояния компонента (например, для рендера резервного интерфейса - вывод сообщения об ошибке) предпочтительнее использовать статический метод getDerivedStateFromError()
#компоненты #жизненныйциклкомпонента #документация
Метод компонента-предохранителя. Вызывается после возникновения ошибки в каком-либо дочернем компоненте.
Входные параметры
👉 error - объект перехваченной ошибки
👉 info - объект с информацией о компоненте, в котором произошла ошибка
Особенности работы
👉 Метод вызывается во время этапа фиксации, поэтому внутри него можно вызывать побочные эффекты.
👉 В дев-режиме ошибки (даже обработанные методом componentDidCatch) всплывают наверх до объекта window. Поэтому можно их перехватывать с помощью обработчика window.onerror. На продакшене этого не происходит, обработанные ошибки дальше не всплывают.
Типичные случаи использования
👍 Логирование ошибок.
👎 Для изменения состояния компонента (например, для рендера резервного интерфейса - вывод сообщения об ошибке) предпочтительнее использовать статический метод getDerivedStateFromError()
#компоненты #жизненныйциклкомпонента #документация
Функция как дочерний компонент
Мы уже говорили про рендер-пропсы. Они позволяют передать в компонент рендер-функцию, которая просто вставляется в нужном месте и генерирует разметку.
Тут можно немного затормозить, поэтому захотелось вернуться к этому моменту. На самом деле ничего странного в этом нет. Помним, что JSX - это обычный JavaScript, поэтому в ней можно использовать любые валидные выражения, включая также и вызовы функций.
https://codepen.io/furrycat/pen/oNZQmgm?editors=0010
Вы помещаете вызов функции внутри фигурных скобок. Функция выполняется, возвращает разметку, которая и выводится.
Это позволяет передавать в разметку динамические аргументы.
#примерыкода #jsx #началоработы
Мы уже говорили про рендер-пропсы. Они позволяют передать в компонент рендер-функцию, которая просто вставляется в нужном месте и генерирует разметку.
Тут можно немного затормозить, поэтому захотелось вернуться к этому моменту. На самом деле ничего странного в этом нет. Помним, что JSX - это обычный JavaScript, поэтому в ней можно использовать любые валидные выражения, включая также и вызовы функций.
https://codepen.io/furrycat/pen/oNZQmgm?editors=0010
Вы помещаете вызов функции внутри фигурных скобок. Функция выполняется, возвращает разметку, которая и выводится.
Это позволяет передавать в разметку динамические аргументы.
#примерыкода #jsx #началоработы
Telegram
React Junior
Рендер-пропсы
Значениями рендер-пропсов являются функции. Но эти функции используются не обычным образом (например, для обработки событий), а для рендера.
В рендер-пропе в компонент передается функция. Компонент вызывает ее в нужном месте своей разметки…
Значениями рендер-пропсов являются функции. Но эти функции используются не обычным образом (например, для обработки событий), а для рендера.
В рендер-пропе в компонент передается функция. Компонент вызывает ее в нужном месте своей разметки…
Контекст
Контекст - это "глобальные переменные" React.
По умолчанию, чтобы глубоко дочерний компонент получил какую-то важную информацию, определенную на верхнем уровне, ее нужно пробросить до него по цепочке пропсов. Но иногда это излишне, особенно если информация нужна буквально каждому компоненту в приложении - надоест пробрасывать.
Яркий пример таких данных - цветовая тема приложения или выбранный язык (локализация).
Важно: применение контекста усложняет повторное использование компонентов, поэтому не стоит им злоупотреблять. Иногда его лучше заменить старой-доброй композицией компонентов или рендер-пропсами.
https://codepen.io/furrycat/pen/NWpEeox?editors=0010
Использование контекста
1. Создать объект контекста с помощью метода React.createContext(defaultValue)
2. Создать провайдер для этого контекста - компонент MyContext.Provider. Все его потомки смогут подписаться на этот контекст (стать потребителями).
3. Передать значение через проп value провайдера. Когда проп изменится, все потребители контекста будут перерендерены.
4. Подписать компонент-потребитель на контекст, указав объект контекста в статическом свойстве класса .contextType.
4. Получить актуальное значение контекста в компоненте-потребителе из свойства this.context.
#контекст #примерыкода #документация
Контекст - это "глобальные переменные" React.
По умолчанию, чтобы глубоко дочерний компонент получил какую-то важную информацию, определенную на верхнем уровне, ее нужно пробросить до него по цепочке пропсов. Но иногда это излишне, особенно если информация нужна буквально каждому компоненту в приложении - надоест пробрасывать.
Яркий пример таких данных - цветовая тема приложения или выбранный язык (локализация).
Важно: применение контекста усложняет повторное использование компонентов, поэтому не стоит им злоупотреблять. Иногда его лучше заменить старой-доброй композицией компонентов или рендер-пропсами.
https://codepen.io/furrycat/pen/NWpEeox?editors=0010
Использование контекста
1. Создать объект контекста с помощью метода React.createContext(defaultValue)
2. Создать провайдер для этого контекста - компонент MyContext.Provider. Все его потомки смогут подписаться на этот контекст (стать потребителями).
3. Передать значение через проп value провайдера. Когда проп изменится, все потребители контекста будут перерендерены.
4. Подписать компонент-потребитель на контекст, указав объект контекста в статическом свойстве класса .contextType.
4. Получить актуальное значение контекста в компоненте-потребителе из свойства this.context.
#контекст #примерыкода #документация
Telegram
React Junior
Рендер-пропсы
Значениями рендер-пропсов являются функции. Но эти функции используются не обычным образом (например, для обработки событий), а для рендера.
В рендер-пропе в компонент передается функция. Компонент вызывает ее в нужном месте своей разметки…
Значениями рендер-пропсов являются функции. Но эти функции используются не обычным образом (например, для обработки событий), а для рендера.
В рендер-пропе в компонент передается функция. Компонент вызывает ее в нужном месте своей разметки…
Context.Consumer
Мы разобрали подписку на контекст с помощью статического свойства класса .contextType и свойства экземпляра this.context. Очевидно, что такая механика доступна только для классовых компонентов, а как быть с функциональными?
Существует другой способ подписаться на изменения контекста - компонент MyContext.Consumer. В качестве дочернего компонента он принимает JavaScript-функцию (не вызов функции, а именно саму функцию). Эта функция будет вызвана с актуальным значением контекста в качестве аргумента. Она должна вернуть фрагмент JSX для рендера.
Значение контекста берется от ближайшего родителя-провайдера.
#контекст #документация
Мы разобрали подписку на контекст с помощью статического свойства класса .contextType и свойства экземпляра this.context. Очевидно, что такая механика доступна только для классовых компонентов, а как быть с функциональными?
Существует другой способ подписаться на изменения контекста - компонент MyContext.Consumer. В качестве дочернего компонента он принимает JavaScript-функцию (не вызов функции, а именно саму функцию). Эта функция будет вызвана с актуальным значением контекста в качестве аргумента. Она должна вернуть фрагмент JSX для рендера.
Значение контекста берется от ближайшего родителя-провайдера.
#контекст #документация
Изменение контекста из вложенного компонента
Контекст может быть обновлен в любом месте приложения. Типичный пример: глубоко вложенная кнопка, нажатие на которую включает темную тему оформления.
Встроенных специальных методов для этого не существует, а решение заключается в том, что в контекст (который представлен объектом) добавляется отдельный метод для изменения значения.
Пример такой реализации можно посмотреть в документации: https://ru.reactjs.org/docs/context.html#updating-context-from-a-nested-component
1. В контексте предусматривается поле theme и метод toggleTheme (по дефолту ничего не делает)
2. Компонент App рендерит провайдер этого контекста и передает ему текущую тему и реализацию для метода toggleTheme
3. Функциональный компонент ThemeTogglerButton подписывается на контекст с помощью компонента Consumer и при нажатии на кнопку, вызывает метод toggleTheme.
#контекст #документация
Контекст может быть обновлен в любом месте приложения. Типичный пример: глубоко вложенная кнопка, нажатие на которую включает темную тему оформления.
Встроенных специальных методов для этого не существует, а решение заключается в том, что в контекст (который представлен объектом) добавляется отдельный метод для изменения значения.
Пример такой реализации можно посмотреть в документации: https://ru.reactjs.org/docs/context.html#updating-context-from-a-nested-component
1. В контексте предусматривается поле theme и метод toggleTheme (по дефолту ничего не делает)
2. Компонент App рендерит провайдер этого контекста и передает ему текущую тему и реализацию для метода toggleTheme
3. Функциональный компонент ThemeTogglerButton подписывается на контекст с помощью компонента Consumer и при нажатии на кнопку, вызывает метод toggleTheme.
#контекст #документация
ru.legacy.reactjs.org
Контекст – React
JavaScript-библиотека для создания пользовательских интерфейсов
Порталы
Порталы необходимы, если дочерний компонент должен рендериться вне родительского DOM. Это актуально для различных модалок и всплывашек, если у родительского элемента задано свойство overflow: hidden.
https://codepen.io/furrycat/pen/VwpgWop?editors=0010
Чтобы компонент отрендерился в определенном месте страницы, нужно вернуть из его метода render результат выполнения метода ReactDOM.createPortal.
Самое приятное - события из порталов распространяются по React-дереву, даже если оно не совпадает с DOM-деревом.
#документация #порталы #примерыкода #началоработы
Порталы необходимы, если дочерний компонент должен рендериться вне родительского DOM. Это актуально для различных модалок и всплывашек, если у родительского элемента задано свойство overflow: hidden.
https://codepen.io/furrycat/pen/VwpgWop?editors=0010
Чтобы компонент отрендерился в определенном месте страницы, нужно вернуть из его метода render результат выполнения метода ReactDOM.createPortal.
Самое приятное - события из порталов распространяются по React-дереву, даже если оно не совпадает с DOM-деревом.
#документация #порталы #примерыкода #началоработы
Ленивые компоненты
React-компоненты можно загружать динамически, по необходимости с помощью функции import(). Для этого существует метод React.lazy, который принимает коллбэк с импортом нужного файла.
https://codesandbox.io/s/react-lazy-react-junior-6rjyv
Компонент, созданный через React.lazy почти ничем не отличается от обычного компонента. То есть вы можете спокойно использовать его в вашем коде. Но пока не понадобится отрендерить этот компонент, он не будет загружен.
Важно
Ленивые компоненты обязательно должны рендериться внутри компонента React.Suspense. Этот компонент обеспечивает отображение запасного интерфейса (проп fallback), пока ленивый компонент грузится. Внутри одного Suspense может быть сколько угодно ленивых компонентов.
Примечание
Чтобы динамический импорт работал, нужно особым образом настроить ваш сборщик. Если вы используете Babel, нужен плагин @babel/plugin-syntax-dynamic-import. В приложениях, созданных с помощью Create React App сборка уже настроена как надо.
Руководство по настройке сплиттинга кода в Webpack: https://webpack.js.org/guides/code-splitting/
#примерыкода #оптимизация #документация #ленивыекомпоненты
React-компоненты можно загружать динамически, по необходимости с помощью функции import(). Для этого существует метод React.lazy, который принимает коллбэк с импортом нужного файла.
https://codesandbox.io/s/react-lazy-react-junior-6rjyv
Компонент, созданный через React.lazy почти ничем не отличается от обычного компонента. То есть вы можете спокойно использовать его в вашем коде. Но пока не понадобится отрендерить этот компонент, он не будет загружен.
Важно
Ленивые компоненты обязательно должны рендериться внутри компонента React.Suspense. Этот компонент обеспечивает отображение запасного интерфейса (проп fallback), пока ленивый компонент грузится. Внутри одного Suspense может быть сколько угодно ленивых компонентов.
Примечание
Чтобы динамический импорт работал, нужно особым образом настроить ваш сборщик. Если вы используете Babel, нужен плагин @babel/plugin-syntax-dynamic-import. В приложениях, созданных с помощью Create React App сборка уже настроена как надо.
Руководство по настройке сплиттинга кода в Webpack: https://webpack.js.org/guides/code-splitting/
#примерыкода #оптимизация #документация #ленивыекомпоненты
CodeSandbox
React Lazy. React Junior - CodeSandbox
React Lazy. React Junior by furrycat.web using react, react-dom, react-scripts
Ленивые компоненты и предохранители
При загрузке ленивого компонента может произойти ошибка (сбой сети), поэтому имеет смысл обернуть его в предохранитель.
#документация #оптимизация #обработкаошибок #предохранители #ленивыекомпоненты
При загрузке ленивого компонента может произойти ошибка (сбой сети), поэтому имеет смысл обернуть его в предохранитель.
#документация #оптимизация #обработкаошибок #предохранители #ленивыекомпоненты
shouldComponentUpdate
Метод жизненного цикла компонента, который вызывается при любом изменении пропсов или состояния ПЕРЕД рендером. Фактически определяет, нужно ли перерисовывать компонент. Поведение по умолчанию - перерендер производится при любом изменении.
Входные параметры
👉 nextProps - объект перехваченной ошибки
👉 nextState - объект с информацией о компоненте, в котором произошла ошибка
Выходные параметры
👉 логическое значение (true/false), которое указывает, нужен ли перерендер
Особенности работы
👉 Если shouldComponentUpdate() возвращает false, то UNSAFE_componentWillUpdate(), render() и componentDidUpdate() не будут вызваны.
👉 Возврат false не предотвращает повторный рендер дочерних компонентов при изменении их состояния.
👉 Не рекомендуется делать глубокое сравнение или использовать JSON.stringify() в shouldComponentUpdate(). Это неэффективно и плохо влияет на производительность.
👉 В будущем React может рассматривать shouldComponentUpdate() как подсказку, а не строгое указание.
Типичные случаи использования
👉 Внутри метода можно сравнить новые пропсы (nextProps) и новое состояние (nextState) с текущими (this.props, this.state). Если изменения не должны вызывать перерендер (например, они не влияют на интерфейс), нужно вернуть из метода false.
Пример
https://codepen.io/furrycat/pen/jOBJmGq?editors=0010
Метод shouldComponentUpdate() разрешает перерендер только при изменении поля this.state.clicks. Поэтому при изменение this.state.counter перендер не происходит. Однако все изменения фиксируются.
#компоненты #жизненныйциклкомпонента #документация #примерыкода
Метод жизненного цикла компонента, который вызывается при любом изменении пропсов или состояния ПЕРЕД рендером. Фактически определяет, нужно ли перерисовывать компонент. Поведение по умолчанию - перерендер производится при любом изменении.
Входные параметры
👉 nextProps - объект перехваченной ошибки
👉 nextState - объект с информацией о компоненте, в котором произошла ошибка
Выходные параметры
👉 логическое значение (true/false), которое указывает, нужен ли перерендер
Особенности работы
👉 Если shouldComponentUpdate() возвращает false, то UNSAFE_componentWillUpdate(), render() и componentDidUpdate() не будут вызваны.
👉 Возврат false не предотвращает повторный рендер дочерних компонентов при изменении их состояния.
👉 Не рекомендуется делать глубокое сравнение или использовать JSON.stringify() в shouldComponentUpdate(). Это неэффективно и плохо влияет на производительность.
👉 В будущем React может рассматривать shouldComponentUpdate() как подсказку, а не строгое указание.
Типичные случаи использования
👉 Внутри метода можно сравнить новые пропсы (nextProps) и новое состояние (nextState) с текущими (this.props, this.state). Если изменения не должны вызывать перерендер (например, они не влияют на интерфейс), нужно вернуть из метода false.
Пример
https://codepen.io/furrycat/pen/jOBJmGq?editors=0010
Метод shouldComponentUpdate() разрешает перерендер только при изменении поля this.state.clicks. Поэтому при изменение this.state.counter перендер не происходит. Однако все изменения фиксируются.
#компоненты #жизненныйциклкомпонента #документация #примерыкода
Telegram
React Junior
componentDidUpdate
Метод вызывается после обновления компонента. Не вызывается при первом рендере.
Входные параметры
👉 prevProps
👉 prevState
👉 snapshot - результат работы метода getSnapshotBeforeUpdate, если он реалиован
Особенности работы
👉 Вызов setState()…
Метод вызывается после обновления компонента. Не вызывается при первом рендере.
Входные параметры
👉 prevProps
👉 prevState
👉 snapshot - результат работы метода getSnapshotBeforeUpdate, если он реалиован
Особенности работы
👉 Вызов setState()…
PureComponent
React.PureComponent это немного прокачанный React.Component, имеющий базовую реализацию метода shouldComponentUpdate().
При каждом изменении PureComponent проводит поверхностное сравнение пропсов и состояния. Если видимых изменений нет, перерендер не происходит.
#компоненты #документация #оптимизация #purecomponent
React.PureComponent это немного прокачанный React.Component, имеющий базовую реализацию метода shouldComponentUpdate().
При каждом изменении PureComponent проводит поверхностное сравнение пропсов и состояния. Если видимых изменений нет, перерендер не происходит.
#компоненты #документация #оптимизация #purecomponent
Telegram
React Junior
shouldComponentUpdate
Метод жизненного цикла компонента, который вызывается при любом изменении пропсов или состояния ПЕРЕД рендером. Фактически определяет, нужно ли перерисовывать компонент. Поведение по умолчанию - перерендер производится при любом изменении.…
Метод жизненного цикла компонента, который вызывается при любом изменении пропсов или состояния ПЕРЕД рендером. Фактически определяет, нужно ли перерисовывать компонент. Поведение по умолчанию - перерендер производится при любом изменении.…
Profiler
React предоставляет встроенные возможности профилирования приложения - с помощью компонента Profiler.
https://codesandbox.io/s/profiler-react-junior-cbidb?file=/src/App.js
Profiler принимает два пропса - id и функцию onRender. onRender вызывается при каждом рендере дочернего дерева и принимает множество аргументов - показателей производительности.
Подробнее об API компонента Profiler в документации: https://ru.reactjs.org/docs/profiler.html
Примечание
Функциональность Profiler доступна только в режиме разработки.
#оптимизация #profiler #документация #примерыкода
React предоставляет встроенные возможности профилирования приложения - с помощью компонента Profiler.
https://codesandbox.io/s/profiler-react-junior-cbidb?file=/src/App.js
Profiler принимает два пропса - id и функцию onRender. onRender вызывается при каждом рендере дочернего дерева и принимает множество аргументов - показателей производительности.
Подробнее об API компонента Profiler в документации: https://ru.reactjs.org/docs/profiler.html
Примечание
Функциональность Profiler доступна только в режиме разработки.
#оптимизация #profiler #документация #примерыкода
CodeSandbox
Profiler. React Junior - CodeSandbox
Profiler. React Junior by furrycat.web using react, react-dom, react-scripts
Оптимизация производительности
Документация утвержает, что React сам по себе довольно умный и производительный. Однако мы можем еще сильнее его ускорить с помощью некоторых действий.
👉 Использование production-сборки
Советы по настройке сборки для разных инструментов есть в документации: https://ru.reactjs.org/docs/optimizing-performance.html
👉 Анализ производительности с помощью Profiler
Краткий обзор компонента Profiler был в предыдущем посте.
👉 Виртуализация длинных списков
Использование метода "оконного доступа" предполагает, что все элементы списка не рендерятся сразу же. На экран выводятся только те элементы, которые пользователь может видеть в данный момент. Это улучшает производительность.
👉 Избежание ненужных согласований
Не каждое изменение пропсов или состояния требует рендерить компонент заново. Чтобы избежать ненужных перерисовок, используйте метод shouldComponentUpdate или наследуйте компонент от PureComponent, который предоставляет базовую реализацию этого метода.
#документация #оптимизация #profiler #purecomponent
Документация утвержает, что React сам по себе довольно умный и производительный. Однако мы можем еще сильнее его ускорить с помощью некоторых действий.
👉 Использование production-сборки
Советы по настройке сборки для разных инструментов есть в документации: https://ru.reactjs.org/docs/optimizing-performance.html
👉 Анализ производительности с помощью Profiler
Краткий обзор компонента Profiler был в предыдущем посте.
👉 Виртуализация длинных списков
Использование метода "оконного доступа" предполагает, что все элементы списка не рендерятся сразу же. На экран выводятся только те элементы, которые пользователь может видеть в данный момент. Это улучшает производительность.
👉 Избежание ненужных согласований
Не каждое изменение пропсов или состояния требует рендерить компонент заново. Чтобы избежать ненужных перерисовок, используйте метод shouldComponentUpdate или наследуйте компонент от PureComponent, который предоставляет базовую реализацию этого метода.
#документация #оптимизация #profiler #purecomponent
ru.legacy.reactjs.org
Оптимизация производительности – React
JavaScript-библиотека для создания пользовательских интерфейсов
PureComponent и иммутабельность данных
Мы уже говорили о том, что класс PureComponent предоставляет базовую реализацию метода shouldComponentUpdate.
Важно понимать, что в этой реализации проводится поверхностное сравнение пропсов и полей состояния. Это значит, что если в состоянии у вас был массив, и вы добавили в него новый элемент с помощью метода push, сам массив остался тем же самым. Следовательно, PureComponent посчитает, что изменений не было, и не обновит представление.
Чтобы этого не произошло, используйте иммутабельные структуры данных. Например, вместо метода push для добавления элемента в массив следует использовать concat или синтаксис расширения массивов (оператор ...). Результатом этих операций будет новый массив, и PureComponent заметит изменение.
#ошибки #purecomponent #оптимизация #документация
Мы уже говорили о том, что класс PureComponent предоставляет базовую реализацию метода shouldComponentUpdate.
Важно понимать, что в этой реализации проводится поверхностное сравнение пропсов и полей состояния. Это значит, что если в состоянии у вас был массив, и вы добавили в него новый элемент с помощью метода push, сам массив остался тем же самым. Следовательно, PureComponent посчитает, что изменений не было, и не обновит представление.
Чтобы этого не произошло, используйте иммутабельные структуры данных. Например, вместо метода push для добавления элемента в массив следует использовать concat или синтаксис расширения массивов (оператор ...). Результатом этих операций будет новый массив, и PureComponent заметит изменение.
#ошибки #purecomponent #оптимизация #документация
Telegram
React Junior
PureComponent
React.PureComponent это немного прокачанный React.Component, имеющий базовую реализацию метода shouldComponentUpdate().
При каждом изменении PureComponent проводит поверхностное сравнение пропсов и состояния. Если видимых изменений нет, перерендер…
React.PureComponent это немного прокачанный React.Component, имеющий базовую реализацию метода shouldComponentUpdate().
При каждом изменении PureComponent проводит поверхностное сравнение пропсов и состояния. Если видимых изменений нет, перерендер…