Что такое ScrollView и когда его стоит использовать?
ScrollView — это встроенный компонент в React Native, предназначенный для создания прокручиваемой области содержимого. Он позволяет отображать элементы, которые не помещаются на экране целиком, с возможностью вертикальной или горизонтальной прокрутки. Под капотом он работает аналогично <ScrollView> в нативных мобильных SDK (например, UIScrollView в iOS и ScrollView в Android).
Основные особенности ScrollView
-
Отображает весь вложенный контент сразу, независимо от его длины.
-
Позволяет прокручивать содержимое вертикально или горизонтально.
-
Используется, когда на экране необходимо разместить большое количество компонентов, которые не помещаются на текущем экране.
-
Хорошо подходит для форм, описаний, больших блоков текста, каруселей и т.п.
-
Не оптимален для списков с очень большим количеством элементов, так как загружает в память всё сразу.
Базовый пример
import { ScrollView, Text, View, StyleSheet } from 'react-native';
export default function App() {
return (
<ScrollView style={styles.container}>
<Text style={styles.header}>Заголовок</Text>
{Array.from({ length: 30 }).map((\_, index) => (
<Text key={index} style={styles.item}>
Элемент {index + 1}
</Text>
))}
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
marginTop: 50,
padding: 10,
},
header: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 10,
},
item: {
fontSize: 18,
marginVertical: 5,
},
});
В этом примере ScrollView позволяет прокручивать список из 30 текстовых элементов, которые не вмещаются на одном экране.
Вертикальная и горизонтальная прокрутка
По умолчанию ScrollView прокручивается вертикально. Для горизонтальной прокрутки:
<ScrollView horizontal={true}>
<Text>Элемент 1</Text>
<Text>Элемент 2</Text>
</ScrollView>
Можно задать как horizontal={true}, так и horizontal (короткая запись).
Props ScrollView (наиболее важные)
Свойство | Описание |
---|---|
horizontal | Горизонтальная прокрутка |
--- | --- |
showsVerticalScrollIndicator | Показывать вертикальный индикатор |
--- | --- |
showsHorizontalScrollIndicator | Показывать горизонтальный индикатор |
--- | --- |
contentContainerStyle | Стилизация обёртки всех вложенных элементов |
--- | --- |
refreshControl | Компонент для обновления содержимого (pull-to-refresh) |
--- | --- |
onScroll | Обработка событий прокрутки |
--- | --- |
scrollEventThrottle | Частота обновления события onScroll |
--- | --- |
pagingEnabled | Переход по страницам, по ширине/высоте экрана |
--- | --- |
keyboardShouldPersistTaps | Поведение касания при активной клавиатуре |
--- | --- |
Когда использовать ScrollView
-
Для отображения форм (например, регистрация, анкета).
-
Для длинных статей, инструкций или условий соглашения.
-
Для горизонтальных списков с изображениями или карточками.
-
Когда весь контент известен заранее и не содержит десятки/сотни элементов.
Когда не стоит использовать ScrollView
ScrollView рендерит всё содержимое сразу, поэтому:
-
При большом количестве элементов (например, списки товаров, чаты) он может вызвать утечки памяти и тормоза.
-
В таких случаях лучше использовать FlatList или SectionList, которые оптимизированы для отображения длинных списков и подгружают данные по мере прокрутки.
Пример: Форма в ScrollView
import { ScrollView, TextInput, Button, View, StyleSheet } from 'react-native';
export default function FormScreen() {
return (
<ScrollView contentContainerStyle={styles.container}>
{Array.from({ length: 15 }).map((\_, index) => (
<TextInput
key={index}
placeholder={\`Поле ввода ${index + 1}\`}
style={styles.input}
/>
))}
<Button title="Отправить" onPress={() => alert('Форма отправлена')} />
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
padding: 20,
},
input: {
borderWidth: 1,
borderColor: '#aaa',
marginBottom: 10,
padding: 10,
borderRadius: 5,
},
});
Обновление содержимого (Pull to Refresh)
Свойство refreshControl позволяет добавить pull-to-refresh:
import { ScrollView, RefreshControl } from 'react-native';
const \[refreshing, setRefreshing\] = useState(false);
<ScrollView
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={() => {
setRefreshing(true);
setTimeout(() => setRefreshing(false), 2000);
}}
/>
}
\>
{/\* контент \*/}
</ScrollView>
Управление прокруткой программно
С помощью ref можно прокручивать вручную:
const scrollRef = useRef();
<ScrollView ref={scrollRef}>
{/\* контент \*/}
</ScrollView>
<Button
title="Прокрутить вниз"
onPress={() => scrollRef.current.scrollToEnd({ animated: true })}
/>
Методы:
-
scrollTo({ x, y, animated })
-
scrollToEnd({ animated })
Советы по использованию ScrollView
-
Используйте contentContainerStyle, а не style, если хотите задать отступы и выравнивание для внутренних элементов.
-
Ограничивайте количество рендеримых элементов, если не требуется отображать всё сразу.
-
Оборачивайте в KeyboardAvoidingView, если есть поля ввода и клавиатура может закрыть часть формы.
-
Указывайте keyboardShouldPersistTaps="handled", чтобы скрывать клавиатуру при тапе вне поля ввода.
Альтернатива: FlatList vs ScrollView
ScrollView | FlatList | |
---|---|---|
Используется при | Небольшом объёме данных | Большом количестве повторяющихся элементов |
--- | --- | --- |
Рендерит | Всё сразу | Только видимые элементы |
--- | --- | --- |
Оптимизация памяти | ❌ | ✅ |
--- | --- | --- |
Поддержка заголовков/футеров | Частично | Полная |
--- | --- | --- |
Поддержка обновления | Через refreshControl | Через onRefresh и refreshing |
--- | --- | --- |
ScrollView — это мощный инструмент, когда нужно сделать прокручиваемый интерфейс с фиксированным набором компонентов или элементов. Он прост в использовании, но требует внимательности при работе с большим объёмом данных, чтобы не перегружать память и не ухудшать производительность приложения.