Я пытаюсь сделать что-то вроде следующего в React JSX
(где ObjectRow является отдельным компонентом):
<tbody>
for (var i=0; i < numrows; i++) {
<ObjectRow/>
}
</tbody>
Я понимаю и понимаю, почему это неверно JSX
, поскольку JSX
сопоставляет вызовы функций. Тем не менее, исходя из шаблона земли и будучи новичком JSX
, я не уверен, как бы я достиг вышеизложенного (добавление компонента несколько раз).
javascript
reactjs
Бен Робертс
источник
источник
let todos = this.props.todos.map((todo) => {return <h1>{todo.title}</h1>})
let todos = this.props.todos.map(t => <h1>{t.title}</h1>)
:)Ответы:
Думайте об этом, как будто вы просто вызываете функции JavaScript. Вы не можете использовать
for
цикл, куда будут идти аргументы для вызова функции:Посмотрите, как функции
tbody
передаетсяfor
цикл в качестве аргумента, и, конечно, это синтаксическая ошибка.Но вы можете создать массив, а затем передать его в качестве аргумента:
Вы можете использовать в основном ту же структуру при работе с JSX:
Между прочим, мой пример JavaScript почти точно то, во что превращается этот пример JSX. Поиграйте с Babel REPL, чтобы понять, как работает JSX.
источник
map
(например, у вас нет коллекции, хранящейся в переменной).key
каждому ребенку. REF: facebook.github.io/react/docs/…key
свойство, а также стиль кода, который на самом деле не используется в базах кода React. Пожалуйста, рассмотрите этот ответ stackoverflow.com/questions/22876978/loop-inside-react-jsx/… как правильный.Не уверен, что это сработает для вашей ситуации, но часто карта - хороший ответ.
Если это был ваш код с циклом for:
Вы можете написать это так с картой :
Синтаксис ES6:
источник
<tbody>{objects.map((o, i) => <ObjectRow obj={o} key={i}/>}</tbody>
используя поддержку Reactify ES6 или Babel.<ul> {objects.map((object:string,i:number)=>{ return <li>{object}</li> })} </ul>
с использованием TypeScriptfor..in
this.props.order.map((k)=><ObjectRow key={k} {...this.props.items[k]} />)
Если у вас еще нет массива,
map()
которому нравится ответ @ FakeRainBrigand, и вы хотите вставить его так, чтобы компоновка источника соответствовала выводу ближе, чем ответ @ SophieAlpert:С синтаксисом ES2015 (ES6) (функции разворота и стрелок)
http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview
На странице caveats говорится, что
Array.from
это требуется для распространения, но в настоящее время (v5.8.23
) этого не происходит при распространении фактическогоArray
. У меня есть проблема с документацией, чтобы прояснить это. Но используйте на свой страх и риск или polyfill.Ваниль ES5
Array.apply
Встроенный IIFE
http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview
Сочетание приемов из других ответов
Держите исходный макет, соответствующий выходу, но сделайте встроенную часть более компактной:
С синтаксисом и
Array
методами ES2015С этим
Array.prototype.fill
вы можете сделать это в качестве альтернативы использованию спреда, как показано выше:(Я думаю, что вы могли бы опустить любой аргумент
fill()
, но я не на 100% об этом.) Спасибо @FakeRainBrigand за исправление моей ошибки в более ранней версииfill()
решения (см. Ревизии).key
Во всех случаях
key
attr снимает предупреждение с помощью сборки разработки, но недоступен для ребенка. Вы можете передать дополнительный атрибут, если хотите, чтобы индекс имелся у ребенка. Смотрите списки и ключи для обсуждения.источник
yield
? Вставка элементов в промежуточный массив выглядит некрасиво, когда у нас есть генераторы. Они работают?[...Array(x)].map(() => <El />))
версия, которая, на мой взгляд, самая элегантная и почему я ее показал. Re: второй вопрос, это отличный момент. Похоже, в JSX нет ничего, что могло бы помешать этому, поэтому это зависит от того, что React или другой потребитель преобразованного JSX делает с аргументами дочерних элементов, чего я не мог сказать, не глядя на источник. Ты знаешь? Это интригующий вопрос.fill()
. Теперь я помню, что причиной, по которой я колебался, является вопрос о том, как необязательность параметров указывается в спецификации ES (придется рассмотреть это когда-нибудь). Запятая - это просто способ исключить элемент массива - в данном случае первый. Вы можете сделать это, если вы хотите, чтобы индексы были с 1..length массива, который вы распространяете, а не 0..length-1 массива расширения (потому что исключенные элементы просто вносят вклад в длину массива и не не имеет соответствующего свойства).Просто с помощью метода map Array с синтаксисом ES6:
Не забывайте
key
собственность.источник
Использование функции Array map - очень распространенный способ циклически проходить по массиву элементов и создавать компоненты в соответствии с ними в React. Это отличный способ создания цикла, который является довольно эффективным и аккуратным способом выполнения ваших циклов в JSX. Это не единственный способ сделать это, но предпочтительный способ.
Кроме того, не забудьте иметь уникальный ключ для каждой итерации, как требуется. Функция карты создает уникальный индекс из 0, но не рекомендуется использовать созданный индекс, но если ваше значение уникально или если есть уникальный ключ, вы можете использовать их:
Кроме того, несколько строк из MDN, если вы не знакомы с функцией map в Array:
источник
Array#map
не асинхронно!Если вы уже используете lodash,
_.times
функция удобна.источник
Вы также можете извлечь вне блока возврата:
источник
Я знаю, что это старый поток, но вы можете проверить React Templates , который позволяет вам использовать шаблоны в стиле jsx в реагировать с несколькими директивами (такими как rt-repeat).
Ваш пример, если бы вы использовали ответные шаблоны, был бы:
источник
Есть несколько способов сделать это. JSX в конечном итоге компилируется в JavaScript, поэтому, пока вы пишете правильный JavaScript, вы будете в порядке.
Мой ответ нацелен на объединение всех чудесных способов, уже представленных здесь:
Если у вас нет массива объектов, просто количество строк:
внутри
return
блока, создаваяArray
и используяArray.prototype.map
:вне
return
блока просто используйте обычный цикл for для JavaScript:Сразу же вызывается выражение функции:
Если у вас есть массив объектов
внутри
return
блока.map()
каждый объект<ObjectRow>
компонента:вне
return
блока просто используйте обычный цикл for для JavaScript:Сразу же вызывается выражение функции:
источник
Если Numrows это массив, и это очень просто.
Тип данных массива в React намного лучше, массив может поддерживать новый массив и поддерживать фильтрацию, уменьшение и т. Д.
источник
Есть несколько ответов, указывающих на использование этого
map
утверждения. Вот полный пример использования итератора в рамках FeatureList компоненты к списку Feature компонентов на основе структуры данных JSON под названием функция .Вы можете просмотреть полный код FeatureList на GitHub. Особенности приспособление перечислены здесь .
источник
Чтобы выполнить цикл несколько раз и вернуться, вы можете добиться этого с помощью
from
иmap
:где
i = number of times
Если вы хотите назначить уникальные идентификаторы ключей в визуализируемых компонентах, вы можете использовать их,
React.Children.toArray
как предложено в документации React.React.Children.toArray
Возвращает дочернюю непрозрачную структуру данных в виде плоского массива с ключами, назначенными каждому дочернему элементу. Полезно, если вы хотите манипулировать коллекциями дочерних элементов в ваших методах рендеринга, особенно если вы хотите переупорядочить или нарезать this.props.children перед его передачей.
источник
Если вы решили преобразовать это внутри возвращение () в визуализации метод, самый простой вариант будет использовать карту () метод. Сопоставьте ваш массив с синтаксисом JSX с помощью функции map (), как показано ниже ( используется синтаксис ES6 ).
Внутри родительского компонента :
Обратите внимание на
key
атрибут, добавленный к вашему дочернему компоненту. Если вы не указали ключевой атрибут, вы можете увидеть следующее предупреждение на своей консоли.Примечание. Одна распространенная ошибка, которую делают люди, - это использование в
index
качестве ключа при итерации, использованиеindex
элемента в качестве ключа является анти-паттерном, и вы можете прочитать больше об этом здесь . Короче говоря, если это НЕ статический список, никогда не используйте его вindex
качестве ключа.Теперь в компоненте ObjectRow вы можете получить доступ к объекту из его свойств.
Внутри компонента ObjectRow
const { object } = this.props
или
const object = this.props.object
Это должно получить вам объект, который вы передали из родительского компонента в переменную
object
в компоненте ObjectRow . Теперь вы можете выплевывать значения в этом объекте в соответствии с вашей целью.Ссылки :
метод map () в Javascript
ECMA Script 6 или ES6
источник
скажем, у нас есть массив элементов в вашем состоянии:
источник
Возможность ES2015 / Babel - использовать функцию генератора для создания массива JSX:
источник
... Или вы также можете подготовить массив объектов и сопоставить его с функцией, чтобы получить желаемый результат. Я предпочитаю это, потому что это помогает мне поддерживать хорошую практику кодирования без логики в возвращении рендера.
источник
Просто используйте
.map()
для циклического просмотра вашей коллекции и возврата<ObjectRow>
предметов с реквизитом из каждой итерации.Предполагая,
objects
что это массив где-то ...источник
ES2015 Array.from с функцией карты + клавиша
Если у вас ничего нет,
.map()
вы можете использоватьArray.from()
этуmap
функцию для повторения элементов:источник
Я использую это:
PS: никогда не забывайте ключ, иначе у вас будет много предупреждений!
источник
.Id
свойства, напримерitems.map( (item, index) => <Foo key={index}>{item}</Foo>
Я склоняюсь к подходу, где логика программирования происходит за пределами возвращаемого значения
render
. Это помогает сохранить то, что на самом деле легко сделать.Так что я бы, наверное, сделал что-то вроде:
По общему признанию, это такой небольшой объем кода, что его вставка может работать нормально.
источник
import { map } from 'lodash'
чтобы вы не импортировали все функции lodash, если они вам не нужны.map()
, только массивы. Это то, что я говорил, lodash хорош для зацикливания объекта.objects
в виду, как в списке вещей, моя ошибка.Вы, конечно, можете решить с помощью .map, как подсказывает другой ответ. Если вы уже используете babel, вы можете подумать об использовании операторов jsx-control. Они требуют небольшой настройки, но я думаю, что это стоит с точки зрения читабельности (особенно для нереагирующего разработчика). Если вы используете linter, есть также eslint-plugin-jsx-control-инструкции
источник
Ваш JSX-код скомпилируется в чистый код JavaScript, любые теги будут заменены
ReactElement
объектами. В JavaScript вы не можете вызывать функцию несколько раз для сбора возвращаемых переменных.Это недопустимо, единственный способ - использовать массив для хранения возвращаемых функцией переменных.
Или вы можете использовать,
Array.prototype.map
который доступен начиная с JavaScript ES5, чтобы справиться с этой ситуацией.Может быть, мы можем написать другой компилятор для воссоздания нового синтаксиса JSX для реализации функции повтора, как в Angular
ng-repeat
.источник
Это можно сделать несколькими способами.
return
сохранением всех элементов в массивеПетля внутри
return
Способ 1
Способ 2
источник
Вот простое решение для этого.
Нет необходимости в отображении и сложном коде. Вам просто нужно поместить строки в массив и вернуть значения для его визуализации.
источник
Поскольку вы пишете синтаксис Javascript внутри JSX-кода, вам нужно заключить Javascript в фигурные скобки.
источник
Вот пример из документа React: JavaScript-выражения как дети
как ваш случай, я предлагаю написать так:
Обратите внимание, что ключ очень важен, потому что React использует ключ для различения данных в массиве.
источник
Я использую это как
источник
Вы можете сделать что-то вроде:
источник
Отличный вопрос
Когда я хочу добавить определенное количество компонентов, я использую вспомогательную функцию.
Определите функцию, которая возвращает JSX:
источник
Вы также можете использовать функцию самовызвания:
источник