Прямое управление¶
Иногда бывает необходимо внести изменения непосредственно в компонент, не используя state/props для запуска повторного рендеринга всего поддерева. Например, при использовании React в браузере иногда требуется напрямую изменить узел DOM, то же самое справедливо и для представлений в мобильных приложениях. setNativeProps
— это эквивалент React Native для установки свойств непосредственно на узле DOM.
Используйте setNativeProps
, когда частые повторные рендеринги создают узкое место в производительности!
Прямые манипуляции не будут тем инструментом, к которому вы часто обращаетесь. Как правило, вы будете использовать его только для создания непрерывной анимации, чтобы избежать накладных расходов на рендеринг иерархии компонентов и согласование множества представлений.
setNativeProps
является императивным и хранит состояние в нативном слое (DOM, UIView и т.д.), а не внутри ваших компонентов React, что делает ваш код более сложным для рассуждений.
Прежде чем использовать его, попробуйте решить свою проблему с помощью setState
и shouldComponentUpdate
.
setNativeProps с TouchableOpacity¶
TouchableOpacity использует setNativeProps
для обновления непрозрачности своего дочернего компонента:
1 2 3 4 5 6 7 |
|
Это позволяет нам написать следующий код и знать, что непрозрачность дочернего объекта будет обновляться в ответ на касания, при этом сам объект не будет знать об этом факте и не потребует изменений в своей реализации:
1 2 3 4 5 |
|
Представим, что функция setNativeProps
недоступна. Один из способов, который мы могли бы реализовать с таким ограничением — хранить значение непрозрачности в состоянии, а затем обновлять это значение при каждом срабатывании onPress
:
1 2 3 4 5 6 7 8 9 10 11 |
|
Это требует больших вычислительных затрат по сравнению с исходным примером — React необходимо перерисовывать иерархию компонентов каждый раз, когда меняется непрозрачность, даже если другие свойства представления и его дочерних элементов не изменились. Обычно эти накладные расходы не вызывают беспокойства, но при выполнении непрерывной анимации и реагировании на жесты разумная оптимизация компонентов может улучшить точность анимации.
Если вы посмотрите на реализацию setNativeProps
в NativeMethodsMixin, то заметите, что она является оберткой вокруг RCTUIManager.updateView
— это точно такой же вызов функции, который происходит в результате повторного рендеринга — см. receiveComponent в ReactNativeBaseComponent.
Составные компоненты и setNativeProps¶
Составные компоненты не поддерживаются нативным представлением, поэтому вы не можете вызвать setNativeProps
для них. Рассмотрим этот пример:
Если вы запустите его, то сразу же увидите ошибку: Дочерний элемент должен быть либо родным, либо передавать setNativeProps родному компоненту
. Это происходит потому, что MyButton
не поддерживается непосредственно нативным представлением, чья непрозрачность должна быть установлена. Об этом можно подумать следующим образом: если вы определяете компонент с помощью createReactClass
, вы не ожидаете, что сможете установить для него style prop и это сработает — вам нужно будет передать style prop дочернему компоненту, если только вы не обертываете родной компонент. Аналогично, мы собираемся передать setNativeProps
дочернему компоненту с поддержкой native.
Передача setNativeProps дочернему компоненту¶
Поскольку метод setNativeProps
существует для любой ссылки на компонент View
, достаточно переслать ссылку на ваш пользовательский компонент на один из компонентов <View />
, которые он рендерит. Это означает, что вызов setNativeProps
на пользовательском компоненте будет иметь такой же эффект, как если бы вы вызвали setNativeProps
на самом обернутом компоненте View
.
Теперь вы можете использовать MyButton
внутри TouchableOpacity
!
Возможно, вы заметили, что мы передали все пропсы дочернему представлению с помощью {...props}
. Причина этого в том, что TouchableOpacity
на самом деле является составным компонентом, и поэтому в дополнение к зависимости от setNativeProps
для своего дочернего компонента, он также требует, чтобы дочерний компонент выполнял обработку касаний. Для этого он передает различные пропсы, которые вызываются обратно к компоненту TouchableOpacity
. TouchableHighlight
, напротив, поддерживается родным представлением и требует только реализации setNativeProps
.
setNativeProps для редактирования значения TextInput¶
Еще один очень распространенный случай использования setNativeProps
— это редактирование значения TextInput. Свойство controlled
для TextInput иногда может пропустить символы, когда bufferDelay
мал и пользователь набирает текст очень быстро. Некоторые разработчики предпочитают полностью отказаться от этого свойства и вместо этого используют setNativeProps
для прямого манипулирования значением TextInput, когда это необходимо. Например, следующий код демонстрирует редактирование ввода при нажатии на кнопку:
Вы можете использовать метод clear
для очистки TextInput
, который очищает текущий текст ввода, используя тот же подход.
Избегание конфликтов с функцией рендеринга¶
Если вы обновляете свойство, которое также управляется функцией рендеринга, вы можете столкнуться с непредсказуемыми и запутанными ошибками, потому что при любом повторном рендеринге компонента и изменении этого свойства, значение, которое было ранее установлено с помощью setNativeProps
, будет полностью проигнорировано и отменено.
setNativeProps & shouldComponentUpdate¶
Путем разумного применения shouldComponentUpdate
вы можете избежать ненужных накладных расходов, связанных с согласованием неизмененных поддеревьев компонентов, до такой степени, что может оказаться достаточно эффективным использовать setState
вместо setNativeProps
.
Другие нативные методы¶
Описанные здесь методы доступны для большинства компонентов по умолчанию, предоставляемых React Native. Обратите внимание, однако, что они не доступны для составных компонентов, которые не поддерживаются непосредственно нативным представлением. Это, как правило, включает большинство компонентов, которые вы определяете в своем собственном приложении.
measure(callback)¶
Определяет местоположение на экране, ширину и высоту в области просмотра данного представления и возвращает значения через асинхронный обратный вызов. В случае успеха обратный вызов будет вызван со следующими аргументами:
x
y
width
height
pageX
pageY
Обратите внимание, что эти измерения доступны только после завершения рендеринга в native. Если вам нужны измерения как можно скорее и вам не нужны pageX
и pageY
, подумайте об использовании свойства onLayout
вместо этого.
Также ширина и высота, возвращаемые measure()
, являются шириной и высотой компонента в области просмотра. Если вам нужен фактический размер компонента, используйте свойство onLayout
.
measureInWindow(callback)¶
Определяет местоположение заданного представления в окне и возвращает значения через async-обратный вызов. Если корневое представление React встроено в другое нативное представление, это даст вам абсолютные координаты. В случае успеха обратный вызов будет вызван со следующими аргументами:
x
y
width
height
measureLayout(relativeToNativeComponentRef, onSuccess, onFail)¶
Аналогично measure()
, но измеряет вид относительно предка, указанного ссылкой relativeToNativeComponentRef
. Это означает, что возвращаемые координаты относятся к началу координат x
, y
вида-предка.
Этот метод также может быть вызван с обработчиком relativeToNativeNode
(вместо ссылки), но этот вариант устарел.
focus()¶
Запрашивает фокус для заданного ввода или представления. Точное поведение будет зависеть от платформы и типа представления.
blur()¶
Убирает фокус с ввода или представления. Это противоположность focus()
.