Видеоуроки, интерактивный редактор и сохранение прогресса — бесплатно, сразу после входа.
ВойтиСоздать аккаунт — бесплатноЗакончили урок?
Войдите, чтобы отмечать прогресс
В этом решении мы создаём систему пагинации для навигации по большому списку из 100 постов.
Array.from() создаёт массив заданной длины. Первый аргумент { length: 100 } - объект с длиной, второй - функция преобразования. Параметр _ (подчёркивание) - это значение элемента (undefined), которое нам не нужно. Параметр i - это индекс от 0 до 99. Мы используем i + 1 для создания номеров от 1 до 100.
currentPage хранит номер текущей страницы, начиная с 1. postsPerPage определяет, сколько элементов показывать на одной странице. Эти два состояния полностью контролируют, какие посты видит пользователь.
Для страницы 3 при 10 постах на странице: последний индекс 3 * 10 = 30, первый индекс 30 - 10 = 20. Массивы в JavaScript начинаются с индекса 0, поэтому это посты с индексами 20-29 (21-30 по порядковому номеру). Эти вычисления работают для любой страницы и любого количества элементов.
Метод slice(start, end) возвращает новый массив с элементами от индекса start до end (не включая end). Для индексов 20 и 30 получим элементы с индексами 20-29 - ровно 10 элементов. slice не изменяет оригинальный массив, а создаёт новый.
Math.ceil() округляет вверх до целого числа. Если у нас 95 постов по 10 на странице, получим 95 / 10 = 9.5, а Math.ceil(9.5) = 10. Нужна 10-я страница для последних 5 постов, поэтому округляем вверх, а не вниз.
Простая функция устанавливает номер страницы. Мы передаём её в кнопки номеров страниц через onClick={() => goToPage(3)}. Стрелочная функция нужна, чтобы передать параметр.
Перед переходом на следующую страницу проверяем, что мы не на последней. Если сейчас страница 10 из 10, условие ложно, и функция ничего не делает. Это предотвращает переход на несуществующую 11-ю страницу.
Аналогично для движения назад - проверяем, что мы не на первой странице. Номера страниц начинаются с 1, поэтому проверяем > 1, а не > 0.
Если страниц мало (5 или меньше), показываем все номера. Если много, используем многоточия для экономии места. Это улучшает UI - вместо 100 кнопок пользователь видит компактную навигацию.
Когда мы на одной из первых трёх страниц, показываем страницы 1-4, многоточие и последнюю страницу. Например: [1] [2] [3] [4] ... [10]. Это даёт контекст - пользователь видит, где он находится и сколько всего страниц.
Когда мы близко к концу (на одной из последних трёх страниц), показываем первую страницу, многоточие и последние 4 страницы. Например: [1] ... [7] [8] [9] [10].
Когда мы в середине списка, показываем первую страницу, многоточие, текущую страницу с соседями, многоточие и последнюю. Например, для страницы 5: [1] ... [4] [5] [6] ... [10]. Пользователь всегда видит контекст - начало, конец и своё положение.
Когда пользователь меняет количество постов на странице, мы сбрасываем на первую страницу. Без этого можно попасть на несуществующую страницу - например, при переходе с 10 на 50 постов страница 8 больше не существует (было 10 страниц по 10 постов, стало 2 страницы по 50).
Атрибут disabled={true} делает кнопку неактивной - она серая и на неё нельзя кликнуть. На первой странице кнопка "Назад" отключена, потому что идти некуда. Это визуальная подсказка пользователю о доступных действиях.
Массив pages содержит и числа, и строки '...'. Для чисел рендерим кнопки, для многоточий - просто текст. Тернарный оператор проверяет тип элемента. Для многоточий используем key с индексом, потому что могут быть два многоточия в массиве.
Кнопка текущей страницы получает класс active для визуального выделения. Пользователь всегда видит, на какой странице находится. CSS использует этот класс для изменения фона или цвета текста.
indexOfFirstPost + 1 - потому что индексы начинаются с 0, а пользователю показываем порядковые номера с 1. Math.min(indexOfLastPost, POSTS.length) нужен для последней страницы - если всего 100 постов, а indexOfLastPost равен 110 (страница 11 по 10 постов), покажем 100, а не 110.
Мы рендерим только currentPosts, а не весь массив POSTS. Это массив из 10 (или другого количества) элементов для текущей страницы. При смене страницы currentPosts пересчитывается, и React перерисовывает список с новыми постами.