React Native — это кроссплатформенная среда разработки мобильных приложений с плавным обучением и множеством встроенных компонентов. Поскольку у него очень активное сообщество разработчиков, для него также доступны сотни сторонних библиотек компонентов с открытым исходным кодом, позволяющих создавать приложения для Android и iOS, ориентируясь только на основную логику приложений. Тем не менее, возможность быстро создавать свои собственные, повторно используемые компоненты с нуля все еще является важным навыком.
-
Мобильное приложение9 лучших шаблонов приложений React Native в 2019 году
-
React NativeНачало работы с собственным шаблоном приложения MStore Pro React
-
реагировать9 шаблонов React Native для изучения и использования
-
React Native5 Реагируйте на собственные наборы пользовательского интерфейса, темы и шаблоны приложений
-
React NativeСоздание приложений электронной коммерции с помощью собственного шаблона MStore Pro React
В этом руководстве я покажу вам, как создать собственный компонент React Native Calendar, используя только ES6 и несколько базовых компонентов, предлагаемых самой платформой.
1. Создание нового проекта
Чтобы не устанавливать React Native CLI и все его зависимости на вашем компьютере, на данный момент я предлагаю вам использовать Expo Snack , бесплатную браузерную IDE для разработки приложений React Native. Если у вас еще нет учетной записи Expo, создайте ее сейчас.
После входа в Expo создайте новый проект Snack, перейдя на вкладку Snacks и нажав ссылку « Создать закуску» .
Среда IDE займет всего несколько секунд, чтобы создать проект и подготовить для него устройство предварительного просмотра. Когда все будет готово, оно должно выглядеть так:
Прежде чем продолжить, убедитесь, что вы удалили весь пример кода, присутствующий в App.js.
2. Создание нового компонента
Чтобы иметь возможность использовать инфраструктуру React и компоненты React Native в своем проекте, добавьте следующие операторы import
в начале файла App.js :
1
2
|
import * as React from ‘react’;
import * as RN from ‘react-native’;
|
Вы создаете пользовательский компонент React, создавая класс, расширяющий класс Component
. Внутри класса вы должны добавить метод с именем render()
, который возвращает код JSX. Следующий код создает компонент с именем MyCalendar
:
1
2
3
4
5
6
7
8
9
|
class MyCalendar extends React.Component {
render() {
return (
<RN.View>
</RN.View>
);
}
}
|
В методе render()
мы в настоящее время возвращаем пустой компонент View
. Он будет служить контейнером для всех других компонентов нашего календаря.
3. Создание констант
Компоненту Calendar нужны два строковых массива: один для хранения названий месяцев и один для хранения названий дней недели.
1
2
3
4
5
6
7
|
months = [«January», «February», «March», «April»,
«May», «June», «July», «August», «September», «October»,
«November», «December»];
weekDays = [
«Sun»,»Mon»,»Tue»,»Wed»,»Thu»,»Fri»,»Sat»
];
|
Далее нам понадобится массив, в котором хранится количество дней в каждом месяце. Для февраля пусть число будет 28. Мы напишем код для обработки високосных лет спустя.
1
|
nDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
4. Инициализировать состояние
Чтобы сделать наш компонент календаря интерактивным, мы должны связать с ним состояние. Сейчас мы собираемся хранить только объект Date
внутри состояния, инициализированный до сегодняшней даты.
1
2
3
|
state = {
activeDate: new Date()
}
|
Состояние, конечно, изменчиво. Когда пользователь нажимает на другую дату в календаре, мы меняем состояние, чтобы использовать новую дату.
5. Генерация матрицы
Матрица с семью строками и семью столбцами достаточно велика для представления любого месяца года. Мы будем использовать первую строку только в качестве заголовка, храня в ней названия дней недели. Чтобы создать и инициализировать эту матрицу, создайте новый метод с именем generateMatrix()
.
1
2
3
4
5
6
7
|
generateMatrix() {
var matrix = [];
// Create header
matrix[0] = this.weekDays;
// More code here
}
|
Прежде чем мы начнем добавлять дни в матрицу, нам нужно определить день начала текущего месяца. Для этого сначала получите год и месяц объекта Date
сохраненного в состоянии. Затем создайте новый объект Date
используя эти значения и 1
, первый день месяца. Вызвав метод getDay()
этого нового объекта, вы получите первый день месяца.
1
2
3
4
|
var year = this.state.activeDate.getFullYear();
var month = this.state.activeDate.getMonth();
var firstDay = new Date(year, month, 1).getDay();
|
Мы не можем напрямую использовать массив nDays
чтобы определить количество дней в текущем месяце. Если февраль месяца, нам нужно вручную добавить дополнительный день при работе с високосными годами. Вот как:
1
2
3
4
5
6
|
var maxDays = this.nDays[month];
if (month == 1) { // February
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
maxDays += 1;
}
}
|
На данный момент у нас есть все данные, которые нам нужны для заполнения остальной части матрицы. В следующем коде показано, как это сделать, используя счетчик, два цикла for
и два простых условия if
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
var counter = 1;
for (var row = 1; row < 7; row++) {
matrix[row] = [];
for (var col = 0; col < 7; col++) {
matrix[row][col] = -1;
if (row == 1 && col >= firstDay) {
// Fill in rows only after the first day of the month
matrix[row][col] = counter++;
} else if (row > 1 && counter <= maxDays) {
// Fill in rows only if the counter’s not greater than
// the number of days in the month
matrix[row][col] = counter++;
}
}
}
return matrix;
|
Обратите внимание, что вам нужно явно инициализировать каждый элемент матрицы 7 x 7. Если вы забудете это сделать, первая или последняя строка может содержать менее семи элементов. Это может привести к проблемам при использовании метода map()
для циклического прохождения матрицы.
6. Рендеринг месяца
Вернувшись в метод render()
, мы должны теперь визуализировать созданную нами матрицу. Поэтому вызовите метод generateMatrix()
внутри него.
1
|
var matrix = this.generateMatrix();
|
Далее, давайте отобразим год и название текущего месяца, добавив компонент Text
к текущему пустому компоненту View
. При желании вы можете использовать style
опору для добавления стилей к тексту.
1
2
3
4
5
6
7
8
|
<RN.Text style={{
fontWeight: ‘bold’,
fontSize: 18,
textAlign: ‘center’
}}>
{this.months[this.state.activeDate.getMonth()]}
{this.state.activeDate.getFullYear()}
</RN.Text>
|
Мы будем использовать flexbox для визуализации содержимого каждой строки матрицы. Точнее, для каждой строки мы будем использовать компонент View
с его параметрами flex
и flexDirection
1
и row
соответственно. Кроме того, чтобы гарантировать, что все элементы строки имеют одинаковую ширину, мы установим параметр justifyContent в justifyContent
равным justifyContent
.
Кроме того, для отображения отдельных элементов матрицы мы снова будем использовать Text
компоненты. Изменяя свойство backgroundColor
компонентов Text
отвечающих за элементы первой строки, мы можем выделить заголовок. Аналогично, если вы хотите выделить воскресенья, используйте свойство color
компонентов Text
отвечающих за элементы первого столбца.
Наш календарь должен быть в состоянии выделить сегодняшнюю дату или дату, которую пользователь выбирает. Поэтому давайте fontWeight
свойство fontWeight
с каждым компонентом Text
. Мы установим его bold
когда его содержимое совпадает с датой в переменной activeDate
нашего состояния.
В следующем коде показано, как использовать метод map()
в качестве альтернативы циклам for
при создании иерархии компонентов для содержимого матрицы:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
var rows = [];
rows = matrix.map((row, rowIndex) => {
var rowItems = row.map((item, colIndex) => {
return (
<RN.Text
style={{
flex: 1,
height: 18,
textAlign: ‘center’,
// Highlight header
backgroundColor: rowIndex == 0 ?
// Highlight Sundays
color: colIndex == 0 ?
// Highlight current date
fontWeight: item == this.state.activeDate.getDate()
?
}}
onPress={() => this._onPress(item)}>
{item != -1 ?
</RN.Text>
);
});
return (
<RN.View
style={{
flex: 1,
flexDirection: ‘row’,
padding: 15,
justifyContent: ‘space-around’,
alignItems: ‘center’,
}}>
{rowItems}
</RN.View>
);
});
|
Чтобы действительно отобразить матрицу, теперь вы должны включить rows
в JSX, возвращаемые методом render()
. Поэтому добавьте следующий код ниже компонента Text
отвечающего за отображение года и названия месяца:
1
|
{ rows }
|
Возможно, вы заметили, что мы onPress
обработчик события onPress
с каждым компонентом Text
отображающим дату. Мы будем использовать его для обновления переменной activeDate
всякий раз, когда пользователи нажимают на дату. Конечно, не забывайте игнорировать Text
компоненты, которые либо пусты, либо отвечают за названия дней недели.
Соответственно, добавьте следующий метод в ваш класс:
1
2
3
4
5
6
7
8
|
_onPress = (item) => {
this.setState(() => {
if (!item.match && item != -1) {
this.state.activeDate.setDate(item);
return this.state;
}
});
};
|
7. Изменение месяцев
Наш компонент календаря будет иметь две кнопки с надписью Next и Previous . Эти кнопки при нажатии должны позволять пользователям переходить с одного месяца на другой. Как вы уже догадались, в их обработчиках событий все, что нам нужно сделать, это получить объект activeDate
и activeDate
или уменьшить его месяц на 1
.
Соответственно, добавьте следующий код в конец JSX, возвращаемого методом render()
:
1
2
3
4
|
<RN.Button title=»Previous»
onPress={() => this.changeMonth(-1)}/>
<RN.Button title=»Next»
onPress={() => this.changeMonth(+1)}/>
|
Затем создайте метод changeMonth()
. Внутри него вы должны сначала вызвать метод setState()
а затем вызвать метод setMonth()
для обновления объекта activeDate
.
1
2
3
4
5
6
7
8
|
changeMonth = (n) => {
this.setState(() => {
this.state.activeDate.setMonth(
this.state.activeDate.getMonth() + n
)
return this.state;
});
}
|
8. Использование компонента
Наш календарный компонент React Native готов. Чтобы использовать его, просто добавьте его в метод render()
вашего класса App
.
1
2
3
4
5
|
export default class App extends React.Component {
render() {
return <MyCalendar/>;
}
}
|
Если вы запустите свой проект сейчас, вы должны увидеть календарь, который выглядит следующим образом:
Вывод
Теперь вы знаете, как создавать и использовать пользовательский компонент календаря React Native, не зависящий от сторонних пакетов. Компонент, который мы создали сегодня, является интерактивным, расширяемым и может использоваться в любом приложении с минимальными изменениями. Не стесняйтесь добавлять больше стилей и функциональности к нему.
Чтобы узнать больше о компонентах React Native, обратитесь к официальной документации . И посмотрите другие наши посты о разработке приложений React Native!
-
Мобильное приложение9 лучших шаблонов приложений React Native в 2019 году
-
React NativeНачало работы с собственным шаблоном приложения MStore Pro React
-
реагировать9 шаблонов React Native для изучения и использования
-
React Native5 Реагируйте на собственные наборы пользовательского интерфейса, темы и шаблоны приложений
-
React NativeСоздание приложений электронной коммерции с помощью собственного шаблона MStore Pro React