Главная » Статьи » Руководство для начинающих по циклам в React JSX

Руководство для начинающих по циклам в React JSX

Руководство для начинающих по циклам в React JSX

От автора: хотите знать, как создавать циклы в React? Узнайте о JSX и о том, как использовать такие методы, как функция map, для создания цикла внутри React JSX и отображения списка элементов.

О JSX в двух словах

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

// JSX example return ( <div> <button onClick={onClickHandler}>Submit</button> </div>
) // The above will be converted to something like this return React.createElement( "div", {}, React.createElement( "button", { onClick: e => {} }, "Submit" ) );

Вы можете узнать об этом больше на сайте React.

Как выполнить в JSX цикл с помощью функции map

Когда я впервые начал работать с React, я довольно рано понял, что не знаю, как перебрать массив и отобразить список элементов. Наиболее распространенный способ сделать это с помощью функции map, которая будет возвращать JSX. Вам редко понадобится цикл, отличный от этого. Ниже вы можете увидеть, как это работает.

import React from ‘react’ const RenderList = props => { const animals = ["Dog", "Bird", "Cat", "Mouse", "Horse"]; return ( <ul> {animals.map(animal => ( <li>{animal}</li> ))} </ul> );
};

Вы должны получить список. Однако, если вы посмотрите журнал консоли, то увидите предупреждение типа “Warning: Each child in a list should have a unique key prop”. Каждый раз, когда вы используете цикл, важно предоставить уникальный атрибут key. Причина в том, что React использует эти ключи для отслеживания изменений, добавления или удаления элементов. Ну, мы могли бы просто использовать индекс цикла, не так ли?

return ( <ul> {animals.map((animal, index) => ( <li key={index}>{animal}</li> ))} </ul> );

Добавив ключ, мы больше не получим предупреждений в консоли. Тем не менее, есть еще кое-что, что вам нужно знать. Использование индекса в качестве ключа в определенных ситуациях может привести к другой проблеме и вызвать ошибки.

Почему key важен в циклах?

Как я упоминал ранее, React использует атрибут key для отслеживания внесенных изменений. Представьте себе сценарий, в котором у вас есть список элементов, которые можно переупорядочить. Если в качестве ключей используются индексы, и мы меняем порядок элементов, узнает ли React об этом? Ну, этого может не произойти, так как, хотя порядок элементов в массиве изменился, ключи не изменились. Следовательно, список не будет перерисован.

Так что, как правило, если у вас есть массив, который можно изменить, используйте уникальный идентификатор. Если он недоступен, то создайте его для каждого элемента, прежде чем отобразить список. В противном случае можно использовать индекс для атрибута key.

// Example with an id const RenderList = props => { const animals = [ { id: 1, animal: "Dog" }, { id: 2, animal: "Bird" }, { id: 3, animal: "Cat" }, { id: 4, animal: "Mouse" }, { id: 5, animal: "Horse" } ]; return ( <ul> {animals.map(item => ( <li key={item.id}>{item.animal}</li> ))} </ul> );
};

До сих пор мы использовали функцию map непосредственно в выражении return. Однако, если хотите, вы можете сначала использовать переменную для хранения результатов map, а затем отобразить содержимое переменной.

const renderAnimals = animals.map(item => ( <li key={item.id}>{item.animal}</li> )); return <ul>{renderAnimals}</ul>;

Если хотите, вы можете даже использовать функцию.

const getAnimalsContent = animals => animals.map(item => ( <li key={item.id}>{item.animal}</li> )); return <ul>{getAnimalsContent(animals)}</ul>;

Использование других циклов в React

В 99,99% случаев я использую функцию map для отображения списка элементов и, честно говоря, не могу вспомнить ни одного сценария, в котором мне понадобился еще один цикл. Тем не менее, вы не привязаны к нему и можете использовать любой цикл для отображения списка. Все это прекрасно работает:

For-of

const getAnimalsContent = animals => { let content = []; for (let item of animals) { content.push(<li key={item.id}>{item.animal}</li>); } return content; }; return <ul>{getAnimalsContent(animals)}</ul>;

For-in

const getAnimalsContent = animals => { let content = []; for (let idx in animals) { const item = animals[idx]; content.push(<li key={item.id}>{item.animal}</li>); } return content; }; return <ul>{getAnimalsContent(animals)}</ul>;

For-standard

const getAnimalsContent = animals => { let content = []; for (let i = 0; i < animals.length; i++) { const item = animals[i]; content.push(<li key={item.id}>{item.animal}</li>); } return content; }; return <ul>{getAnimalsContent(animals)}</ul>;

Filter

Функция Filter может использоваться вместе с фильтрацией элементов map перед их отображением. Например, в приведенном ниже примере будут отображаться только элементы «Mouse» и «Horse».

// Filter out any animals that do not contain ‘e’ character. const getAnimalsContent = animals => animals .filter(item => item.animal.includes("e")) .map(item => <li key={item.id}>{item.animal}</li>); return <ul>{getAnimalsContent(animals)}</ul>;

Reduce

Приведенный выше пример filter можно улучшить с помощью метода reduce, и вместо двух циклов — одного для фильтрации и одного для создания контента JSX — у нас будет только один.

const getAnimalsContent = animals => animals.reduce((acc, item) => { if (item.animal.includes("e")) { acc.push(<li key={item.id}>{item.animal}</li>); } return acc; }, []); return <ul>{getAnimalsContent(animals)}</ul>;

Если по какой-либо причине вы хотите поэкспериментировать, вы можете даже использовать рекурсию для отображения списка. Однако я бы не советовал делать это, и в большинстве случаев вам действительно следует придерживаться функции map.

const getAnimalsContent = (animals, content = []) => { if (!animals.length) return content; const [item, ...restAnimals] = animals; content.push(<li key={item.id}>{item.animal}</li>); return getAnimalsContent(restAnimals, content); }; return <ul>{getAnimalsContent(animals)}</ul>;

Как вы можете видеть, существует несколько различных способов отображения списка элементов в React. Я надеюсь, что после прочтения этой статьи вы будете более уверенно использовать React и циклы в JSX.

Автор: Thomas Findlay

Источник: https://www.telerik.com

Редакция: Команда webformyself.