Как перебрать массивы в React
При создании любого типа веб-приложения очень часто вам нужно обрабатывать массив данных. В этой статье я покажу вам, как перебирать массив данных, используя лучшие практики React, используя реальные примеры, которые вы можете взять и использовать в своих собственных веб-приложениях.
Вы использовали раньше метод map?
Метод map() создает новый массив с результатами вызова предоставленной функции для каждого элемента в вызывающем массиве.
Таким образом, функция map была введена в Javascript в ES2015. Это значительно упрощает процесс зацикливания и избавляет от необходимости использовать цикл for или функцию forEach. Теперь есть некоторые различия между циклом for, forEach и map, но мы не будем вдаваться в них здесь. Документация React настоятельно рекомендуют использовать функцию map не только для простоты, но и потому, что она создает новый массив из данных, а не пытается изменить / перезаписать существующие данные.
Этот второй момент жизненно важен. Если вы не знаете, как использовать функции map, я рекомендую вам прочесть эту статью об использовании map, filter и reduce.
Перебирая множество предметов в корзине
Давайте представим, что мы создаем сайт электронной коммерции, где мы продаем одежду. Наше приложение, скорее всего, будет иметь корзину, в которую будут добавлены товары. Итак, для начала, наша корзина будет выглядеть примерно так.
let shoppingCart = [];
Но после добавления нескольких элементов это может выглядеть примерно так:
let shoppingCart = [ {id: 35, item: 'jumper', color: 'red', size: 'medium', price: 20}, {id: 42, item: 'shirt', color: 'blue', size: 'medium', price: 15}, {id: 71, item: 'socks', color: 'black', size: 'all', price: 5}, ]
Теперь на нашей странице корзины покупок мы хотим вывести эти элементы, чтобы пользователь мог видеть, что они заказали. Давайте рассмотрим два очень похожих способа, которыми мы можем справиться с этим.
Внутри нашего конструктора класса App мы создадим this.items и назначим его this.state.cart
(помните, что именно здесь мы храним элементы, которые добавляются в корзину). Затем мы используем функцию map ES2015 для циклического прохождения каждого элемента в this.state.cart.
Мы передаем нашей функции map два параметра. Первый - это элемент, который просто соответствует одному элементу в нашем массиве this.state.cart
. Второй - это ключ, который React использует, чтобы помочь своему рендереру отслеживать каждый отдельный элемент. Как вы, возможно, заметили, мы не устанавливаем key
внутреннюю часть нашего this.state.cart
, мы просто передаем идентификатор элемента в качестве ключа, ссылаясь внутри нашей функции map на item.id
. В любом случае, мы затем выводим тег
- с
{item.name}
.
Давайте просто кратко рассмотрим этот кусок кода полностью:
this.items = this.state.cart.map((item, key) =>
Затем в нашем коде, когда мы захотим его использовать, мы просто создадим внешний тег
- .
Второй способ, которым мы могли бы справиться с этим, очень похож и может показаться немного более знакомым.
Вместо того, чтобы помещать наш блок кода this.item в конструктор класса, мы могли бы просто поместить его в начало нашей функции render(), вот так:
render() { const items = this.state.cart.map((item, key) =>
Это позволяет нам использовать более традиционный синтаксис const (или var или let, если вы предпочитаете).
Если мы делаем так, это также означает, что мы можем вывести список следующим образом:
-
{items}
Теперь некоторые люди будут утверждать, что вы не должны загрязнять функцию render()
, но когда пишете что-то довольно простое и не очень сложное (я говорю о тысячах и тысячах строк кода), это действительно не имеет значения. Поэтому я бы порекомендовал вам пойти по тому пути, который вам удобнее. По мере продвижения в React вы найдете стиль, наиболее подходящий для вашего проекта.
Итак, мы знаем, как отображать списки, используя циклы. Но что, если мы хотим перебрать данные для вывода множества дочерних компонентов? Как мы можем это сделать?
Ну, это на самом деле довольно просто и очень похоже на то, что мы уже делали.
Итак, давайте представим, что в нашем магазине есть следующие товары:
shop: [ {id: 35, name: 'jumper', color: 'red', price: 20}, {id: 42, name: 'shirt', color: 'blue', price: 15}, {id: 56, name: 'pants', color: 'green', price: 25}, {id: 71, name: 'socks', color: 'black', price: 5}, {id: 72, name: 'socks', color: 'white', price: 5}, ]
И просто, чтобы дать вам более ясную картину, этот shop существует внутри this.state, внутри конструктора. Все это выглядит так:
class App extends Component { constructor(props) { super(props); this.state = { cart: [], shop: [ {id: 35, name: 'jumper', color: 'red', price: 20}, {id: 42, name: 'shirt', color: 'blue', price: 15}, {id: 56, name: 'pants', color: 'green', price: 25}, {id: 71, name: 'socks', color: 'black', price: 5}, {id: 72, name: 'socks', color: 'white', price: 5}, ] } }
Таким образом , у нас есть переменная shop со списком товаров, и теперь мы хотим создать дочерний компонент, который мы называем Item.js. Весь файл компонента выглядит так:
import React, {Component} from 'react'; class Item extends Component { render() { return (); } } export default Item;{this.props.item.name}
{this.props.item.color}
${this.props.item.price}
Если вы не уверены, мы вызываем, this.props.item
потому что мы передаем this.state.item в дочерний компонент, когда мы вызываем его внутри родительского компонента. Это может звучать немного странно, но потерпите, и все это будет иметь смысл через мгновение!
Итак, возвращаясь к циклу, вот что мы напишем, чтобы просмотреть элементы в нашем магазине:
Товары для продажи{this.state.shop.map((item, key) =>- )}
Как видите, это почти та же концепция, что мы использовали ранее. Единственная разница здесь в том, что вместо вывода тегов
- мы теперь используем - это компонент Item.js, о котором мы упоминали только что! Это так просто!
Поэтому, когда мы вызываем this.props.item внутри компонента Item.js , это ссылка , а точнее item={item}
. Поэтому, если бы мы назвали это product={item}
, мы бы вместо этого обратились к this.props.product
. Есть смысл?
Возможно, вы заметили, что нам пришлось обернуть всю функциональность внутри фигурных скобок {}. Это необходимо для того, чтобы React мог понять, что вы пытаетесь выразить функцию, а не просто выводить простой текст.
Еще одна вещь, которую следует также отметить, заключается в том, что все три различных способа, которыми мы проходили через данные, можно взаимозаменять. Так что, если вы хотите перебрать массив дочерних компонентов, но предпочли первый метод, который мы вам показали, смело можете использовать его! В конце концов, это все обычный Javascript!