Render react что это
3.12 Паттерн: свойство render
Компонент со свойством render принимает функцию, которая возвращает элемент React, и вызывает её вместо реализации своей собственной логики отрисовки.
В этом разделе мы обсудим, почему полезно использовать свойство для отрисовки.
3.12.1 Используйте «свойство render» для сквозной функциональности
Компоненты являются основным элементом повторного использования кода в React, но не всегда очевидно, как совместно использовать состояние или поведение, которые один компонент инкапсулирует в другие компоненты, нуждающиеся в этом состоянии.
Например, следующий компонент отслеживает позицию мыши в веб-приложении:
Когда курсор перемещается по экрану, компонент отображает его координаты (x, y) в
Теперь возникает вопрос: как мы можем повторно использовать это поведение в другом компоненте? Другими словами, если другой компонент должен знать о позиции курсора, можем ли мы инкапсулировать это поведение таким образом, чтобы можно было легко поделиться им с этим компонентом?
Теперь компонент инкапсулирует все поведение, связанное с прослушиванием событий mousemove и хранением позиции (x, y) курсора, но он еще не может быть использован повторно.
Такой подход будет работать для нашего конкретного случая, но мы не достигли цели по-настоящему инкапсулировать поведение для повторного использования. Теперь, каждый раз, когда нам нужна позиция мыши для какого-нибудь другого случая, мы должны создать новый компонент (т. е. по существу другой ), который отрисовывает что-то конкретное для данного случая.
Вот где в силу вступает паттерн «свойство render»: вместо жесткого кодирования внутри компонента и изменения результата его отрисовки, мы можем предоставить компоненту особое свойство-функцию, которое он использует для динамического определения того, что необходимо отрисовать. Это особое свойство и есть «свойство render».
Более конкретно: свойство render является свойством-функцией, которую компонент использует, для определения того, что ему необходимо отрисовывать.
Таким образом, использование свойства render дает возможность применить любой паттерн.
3.12.2 Использование свойств, отличных от «render»
И помните, что на самом деле нет необходимости указывать свойство children в списке «атрибутов» вашего JSX-элемента. Вместо этого вы можете поместить его прямо внутри этого элемента!
Вы можете увидеть этот подход в react-motion API.
3.12.3 Будьте внимательны, когда используете паттерн «свойство render» с React.PureComponent
Чтобы обойти эту проблему, иногда вы можете определить свойство как метод экземпляра, например:
Рендеринг элементов
Элементы — мельчайшие кирпичики React-приложений.
Элемент описывает то, что вы хотите увидеть на экране:
В отличие от DOM-элементов, элементы React — это простые объекты, не отнимающие много ресурсов. React DOM обновляет DOM, чтобы он соответствовал переданным React-элементам.
Элементы можно перепутать с более известной концепцией «компонентов». С компонентами мы ознакомимся в следующей главе. Элементы — это то, «из чего сделаны» компоненты, и мы рекомендуем вам дочитать эту главу, прежде чем двигаться дальше.
Рендеринг элемента в DOM
Допустим, в вашем HTML-файле есть
Мы назовём его «корневым» узлом DOM, так как React DOM будет управлять его содержимым.
Обычно в приложениях, написанных полностью на React, есть только один корневой элемент. При встраивании React в существующее приложение вы можете рендерить во столько независимых корневых элементов, во сколько посчитаете нужным.
Для рендеринга React-элемента в корневой узел DOM вызовите ReactDOM.render() с React-элементом и корневым DOM-узлом в качестве аргументов:
На странице будет написано «Hello, world».
Обновление элементов на странице
Элементы React иммутабельны. После создания элемента нельзя изменить его потомков или атрибуты. Элемент похож на кадр в фильме: он отражает состояние интерфейса в конкретный момент времени.
Рассмотрим пример с часами:
На практике большинство React-приложений вызывают ReactDOM.render() только один раз. В следующем разделе вы узнаете, как можно обновлять интерфейс при помощи компонента с состоянием.
Мы рекомендуем не пропускать главы, поскольку каждая следующая глава опирается на знания из предыдущей.
React обновляет только то, что необходимо
React DOM сравнивает элемент и его дочернее дерево с предыдущей версией и вносит в DOM только минимально необходимые изменения.
Вы можете убедиться в этом на последнем примере с помощью инструментов разработки в браузере:
Несмотря на то, что мы создаём элемент, описывающий всё UI-дерево, каждую секунду React DOM изменяет только текстовый узел, содержимое которого изменилось.
Проще описать, как интерфейс выглядит в конкретный момент, чем как он изменяется с течением времени. По нашему опыту, такой подход позволяет избавиться от целого класса ошибок.
Отрисовка элементов
Элементы — это самые маленькие строительные блоки приложений React.
Элемент описывает, что вы хотите видеть на экране:
Unlike browser DOM elements, React elements are plain objects, and are cheap to create. React DOM takes care of updating the DOM to match the React elements.
В отличие от DOM-элементов браузера, элементы React — обычные объекты, лёгкие для создания. React DOM берёт заботу по обновлению DOM на себя для соответствия элементам React.
Может сбить с толку элементы с более широко известной концепцией «компонентов». Мы представим компоненты в следующем разделе (/docs/components-and-props.html). Элементы — это то, что из чего компоненты «сделаны», и мы рекомендуем вам прочитать этот раздел, прежде чем идти вперёд.
Отрисовка элемента в DOM
Предположим, что в вашем файле HTML есть
Мы называем это «корневым» узлом DOM, потому что всё внутри него будет управляться DOM React.
У приложений, созданных только с использованием React, обычно есть только единственный корневой узел DOM. Если вы интегрируете React в существующее приложение, у вас может быть как можно больше изолированных корневых узлов DOM.
Чтобы отрисовать элемент React в корневом узле DOM, передайте его в ReactDOM.render() :
На странице отобразится «Привет, мир».
Обновление отрисованного элемента
React-элементы — неизменяемы. Создав однажды элемент, вы не сможете изменить его дочерние элементы или атрибуты. Элемент похож на один кадр в фильме: он представляет собой пользовательский интерфейс в определённый момент времени.
Рассмотрим этот пример тикающих часов:
Мы рекомендуем вам не пропускать эти темы, потому что они опираются друг на друга.
React обновляет только то, что необходимо
DOM React сравнивает элемент и его дочерние элементы с предыдущими и применяет только обновления DOM, необходимые для преобразования DOM в желаемое состояние.
Вы можете убедиться в том, проверив последний пример с помощью инструментов браузера:
Несмотря на то, что мы создаём элемент, описывающий всё дерево пользовательского интерфейса на каждом тике, только текстовый узел, содержимое которого изменилось, обновляется в DOM React.
По нашему опыту, размышление о том, как пользовательский интерфейс должен выглядеть в любой данный момент, а не то, как его менять со временем, устраняет целый класс багов.
Рендер-пропсы
Термин «рендер-проп» относится к возможности компонентов React разделять код между собой с помощью пропа, значение которого является функцией.
Компонент с рендер-пропом берёт функцию, которая возвращает React-элемент, и вызывает её вместо реализации собственного рендера.
Такой подход, в частности, применяется в библиотеках React Router, Downshift и Formik.
В этой статье мы покажем, чем полезны и как писать рендер-пропсы.
Использование рендер-пропа для сквозных задач
Компоненты — это основа повторного использования кода в React. Однако бывает неочевидно, как сделать, чтобы одни компоненты разделяли своё инкапсулированное состояние или поведение с другими компонентами, заинтересованными в таком же состоянии или поведении.
Например, следующий компонент отслеживает положение мыши в приложении:
Когда курсор перемещается по экрану, компонент отображает координаты (x, y) внутри
Возникает вопрос: как мы можем повторно использовать это поведение в другом компоненте? То есть если другому компоненту необходимо знать о позиции курсора, можем ли мы как-то инкапсулировать это поведение, чтобы затем легко использовать его в этом компоненте?
Теперь компонент инкапсулирует всё поведение, связанное с обработкой событий mousemove и хранением позиций курсора (x, y), но пока не обеспечивает повторного использования.
Для начала вы можете отрендерить внутри метода render компонента следующим образом:
Этот подход будет работать для конкретного случая, но мы не достигли основной цели — инкапсулировать поведение с возможностью повторного использования. Теперь, каждый раз когда мы хотим получить позицию мыши для разных случаев, нам требуется создавать новый компонент (т. е. другой экземпляр ), который рендерит что-то специально для этого случая.
Вот здесь рендер-проп нам и понадобится: вместо явного указания внутри компонента, и трудозатратных изменений на выводе рендера, мы предоставляем функцию в качестве пропа, с которой мы используем динамическое определение того, что нужно передавать в рендер-проп.
Иными словами, рендер-проп — функция, которая сообщает компоненту что необходимо рендерить.
Эта техника позволяет сделать легко портируемым поведение, которое мы хотим повторно использовать. Для этого следует отрендерить компонент с помощью рендер-пропа, который сообщит, где отрендерить курсор с текущим положением (x, y).
Таким образом, рендер-пропы позволяют реализовать любой из описанных выше паттернов.
Использование пропсов, отличных от render (как название передаваемого свойства)
И запомните, проп children не обязательно именовать в списке «атрибутов» вашего JSX-элемента. Вместо этого, вы можете поместить его прямо внутрь элемента!
Эту технику можно увидеть в действии в API библиотеки react-motion.
Поскольку этот метод не совсем обычен, вы, вероятно, захотите явно указать, что children должен быть функцией в вашем propTypes при разработке такого API.
Будьте осторожны при использовании рендер-проп вместе с React.PureComponent
Чтобы решить эту проблему, вы можете определить проп как метод экземпляра, например так:
Условный рендеринг
React позволяет разделить логику на независимые компоненты. Эти компоненты можно показывать или прятать в зависимости от текущего состояния.
Рассмотрим два компонента:
Элементы React можно сохранять в переменных. Это может быть удобно, когда какое-то условие определяет, надо ли рендерить одну часть компонента или нет, а другая часть компонента остаётся неизменной.
Рассмотрим ещё два компонента, представляющих кнопки Войти (Login) и Выйти (Logout).
Встроенные условия if с логическим оператором &&
Вы можете внедрить любое выражение в JSX, заключив его в фигурные скобки. Это правило распространяется и на логический оператор && языка JavaScript, которым можно удобно вставить элемент в зависимости от условия:
Встроенные условия if-else с тернарным оператором
Вот как этот метод можно использовать, чтобы отрендерить кусочек текста.
Этот метод можно использовать и с выражениями покрупнее, но это может сделать код менее очевидным:
Как в JavaScript, так и в React выбор синтаксиса зависит от ваших предпочтений и принятого в команде стиля. Не забывайте, что если какое-то условие выглядит очень сложным, возможно пришло время извлечь часть кода в отдельный компонент.
Предотвращение рендеринга компонента
В редких случаях может потребоваться позволить компоненту спрятать себя, хотя он уже и отрендерен другим компонентом. Чтобы этого добиться, верните null вместо того, что обычно возвращается на рендеринг.
Сам факт возврата null из метода render компонента никак не влияет на срабатывание методов жизненного цикла компонента. Например, componentDidUpdate будет всё равно вызван.