Spec-Zone.ru › React Native

Прямое управление

Иногда необходимо внести изменения непосредственно в компонент, не используя состояние/свойства для повторного рендеринга всего поддерева. Например, при использовании React в браузере иногда требуется напрямую модифицировать узел DOM, и то же самое справедливо для представлений в мобильных приложениях. setNativeProps — это эквивалент React Native для непосредственного задания свойств узла DOM.

Используйте setNativeProps в случае, когда частый повторный рендеринг создаёт проблему с производительностью!

Прямое управление не будет инструментом, которым вы часто пользуетесь. Обычно вы его используете только для создания непрерывных анимаций, чтобы избежать накладных расходов на рендеринг иерархии компонентов и согласование многих представлений. setNativeProps является обязательным и хранит состояние на родном уровне (DOM, UIView и т. д.), а не внутри ваших React-компонентов, что усложняет понимание вашего кода.

Прежде чем использовать его, попробуйте решить проблему с помощью setState и shouldComponentUpdate.

setNativeProps с TouchableOpacity

TouchableOpacity использует setNativeProps внутри для обновления непрозрачности дочернего компонента:

const viewRef = useRef();
const setOpacityTo = useCallback((value) => {
  // Redacted: animation related code
  viewRef.current.setNativeProps({
    opacity: value
  });
}, []);

Это позволяет нам написать следующий код и знать, что непрозрачность дочернего элемента будет обновляться в ответ на нажатия, без необходимости для дочернего элемента иметь какое-либо представление о этом факте или требовать каких-либо изменений в его реализации:

<TouchableOpacity onPress={handlePress}>
  <View>
    <Text>Press me!</Text>
  </View>
</TouchableOpacity>

Предположим, что setNativeProps был недоступен. Один из способов его реализации с этим ограничением — хранить значение непрозрачности в состоянии, а затем обновлять это значение всякий раз, когда onPress срабатывает:

const [buttonOpacity, setButtonOpacity] = useState(1);
return (
  <TouchableOpacity
    onPressIn={() => setButtonOpacity(0.5)}
    onPressOut={() => setButtonOpacity(1)}>
    <View style={{ opacity: buttonOpacity }}>
      <Text>Press me!</Text>
    </View>
  </TouchableOpacity>
);

Это вычислительно затратно по сравнению с исходным примером — React необходимо повторно отрисовать иерархию компонентов каждый раз, когда непрозрачность изменяется, даже если другие свойства представления и его дочерних элементов не изменились. Обычно эти накладные расходы не являются проблемой, но при выполнении непрерывных анимаций и реагировании на жесты тщательная оптимизация ваших компонентов может улучшить качество анимации.

Если вы посмотрите на реализацию setNativeProps в NativeMethodsMixin, вы заметите, что это обёртка вокруг RCTUIManager.updateView — это тот же вызов функции, который происходит при повторном рендеринге — см. receiveComponent в ReactNativeBaseComponent.

Составные компоненты и setNativeProps

Составные компоненты не поддерживаются родным представлением, поэтому вы не можете вызвать setNativeProps для них. Рассмотрим этот пример:

Если вы запустите это, вы сразу увидите эту ошибку: Touchable child must either be native or forward setNativeProps to a native component. Это происходит потому, что MyButton не поддерживается напрямую родным представлением, непрозрачность которого необходимо установить. Вы можете представить это так: если вы определите компонент с createReactClass, вы не ожидаете, что сможете установить свойство стиля и заставить его работать — вам нужно будет передать свойство стиля дочернему элементу, если только вы не обёртываете родной компонент. Аналогично, мы будем передавать setNativeProps в дочерний компонент с родной поддержкой.

Передача 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
  • ширина
  • высота
  • pageX
  • pageY

Обратите внимание, что эти измерения недоступны до завершения рендеринга в родном коде. Если вам нужны измерения как можно скорее, и вам не нужны pageX и pageY, рассмотрите использование свойства onLayout вместо этого.

Также ширина и высота, возвращаемые measure(), представляют собой ширину и высоту компонента в области просмотра. Если вам нужен фактический размер компонента, рассмотрите использование свойства onLayout вместо этого.

measureInWindow(callback)

Определяет расположение данного представления в окне и возвращает значения через асинхронный обратный вызов. Если корневое представление React встроено в другое родное представление, это даст вам абсолютные координаты. При успехе обратный вызов будет вызван со следующими аргументами:

  • x
  • y
  • ширина
  • высота

measureLayout(relativeToNativeComponentRef, onSuccess, onFail)

Подобно measure(), но измеряет представление относительно предка, указанного ссылкой relativeToNativeComponentRef. Это означает, что возвращаемые координаты относительны к началу x, y предка.

Этот метод также может быть вызван с обработчиком relativeToNativeNode (вместо ссылки), но этот вариант устарел.

focus()

Запрашивает фокус для данного входного или представления. Точное поведение, которое будет выполнено, зависит от платформы и типа представления.

blur()

Удаляет фокус с входного или представления. Это противоположность focus().

© 2022 Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://reactnative.dev/docs/direct-manipulation

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API