Estou tentando fazer algo parecido com o seguinte no React JSX
(onde o ObjectRow é um componente separado):
<tbody>
for (var i=0; i < numrows; i++) {
<ObjectRow/>
}
</tbody>
Percebo e entendo por que isso não é válido JSX
, pois JSX
mapeia as chamadas de função. No entanto, vindo do modelo de terra e sendo novo JSX
, não tenho certeza de como conseguiria o que foi mencionado acima (adicionando um componente várias vezes).
javascript
reactjs
Ben Roberts
fonte
fonte
let todos = this.props.todos.map((todo) => {return <h1>{todo.title}</h1>})
let todos = this.props.todos.map(t => <h1>{t.title}</h1>)
:)Respostas:
Pense nisso como se estivesse apenas chamando funções JavaScript. Você não pode usar um
for
loop no qual os argumentos para uma chamada de função iriam:Veja como a função
tbody
está passando umfor
loop como argumento e, claro, isso é um erro de sintaxe.Mas você pode criar uma matriz e depois passar isso como argumento:
Você pode usar basicamente a mesma estrutura ao trabalhar com JSX:
Aliás, meu exemplo de JavaScript é quase exatamente o que esse exemplo de JSX se transforma. Brinque com o Babel REPL para ter uma ideia de como o JSX funciona.
fonte
map
(por exemplo, você não tem uma coleção armazenada em uma variável).key
a cada filho. Você podekey
propriedade e também um estilo de código que não é realmente usado nas bases de código do React. Considere esta resposta como stackoverflow.com/questions/22876978/loop-inside-react-jsx/… como correta.Não tenho certeza se isso funcionará para a sua situação, mas geralmente o mapa é uma boa resposta.
Se esse era seu código com o loop for:
Você poderia escrever assim com o mapa :
Sintaxe ES6:
fonte
<tbody>{objects.map((o, i) => <ObjectRow obj={o} key={i}/>}</tbody>
usando o suporte ES6 do Reactify ou Babel.<ul> {objects.map((object:string,i:number)=>{ return <li>{object}</li> })} </ul>
usando TypeScriptfor..in
this.props.order.map((k)=><ObjectRow key={k} {...this.props.items[k]} />)
Se você ainda não possui uma matriz para
map()
gostar da resposta de @ FakeRainBrigand e deseja incorporar isso, o layout de origem corresponde à saída mais próxima da resposta de @ SophieAlpert:Com sintaxe do ES2015 (ES6) (funções de propagação e seta)
http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview
Re: transpiling com Babel, sua página de advertências diz que
Array.from
é necessário para a propagação, mas no momento (v5.8.23
) isso não parece ser o caso ao espalhar um realArray
. Eu tenho um problema de documentação aberto para esclarecer isso. Mas use por seu próprio risco ou polyfill.Vanilla ES5
Array.apply
Inline IIFE
http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview
Combinação de técnicas de outras respostas
Mantenha o layout de origem correspondente à saída, mas torne a peça incorporada mais compacta:
Com sintaxe e
Array
métodos do ES2015Com
Array.prototype.fill
você, você poderia fazer isso como uma alternativa ao uso do spread, como ilustrado acima:(Acho que você realmente pode omitir qualquer argumento
fill()
, mas não sou 100% nisso.) Obrigado a @FakeRainBrigand por corrigir meu erro em uma versão anterior dafill()
solução (consulte as revisões).key
Em todos os casos, o
key
attr alivia um aviso com a construção do desenvolvimento, mas não está acessível no filho. Você pode passar um atributo extra se desejar que o índice esteja disponível no filho. Consulte Listas e chaves para discussão.fonte
yield
? A inserção de elementos em uma matriz intermediária é meio feia quando temos geradores. Eles trabalham?[...Array(x)].map(() => <El />))
versão, que eu acho que é a mais elegante, e por que eu a destaquei. Re: a segunda pergunta, esse é um ótimo ponto. Parece que não existe nada sobre o JSX que o impeça, portanto depende do que o React ou outro consumidor de JSX transformado faça com os argumentos filhos, o que eu não poderia dizer sem olhar a fonte. Você sabe? É uma pergunta intrigante.fill()
. Lembro-me agora que o motivo pelo qual hesitei é uma pergunta sobre como a opcionalidade dos parâmetros é indicada na especificação ES (tem que analisar isso em algum momento). A vírgula é apenas uma maneira de eliminar um elemento da matriz - nesse caso, o primeiro. Você pode fazer isso se quiser que os índices sejam de 1..length da matriz que você está espalhando, em vez de 0..length-1 da matriz de dispersão (porque elementos elididos apenas contribuem para o comprimento da matriz e não ' tem uma propriedade correspondente).Simplesmente usando o método Array do mapa com sintaxe ES6:
Não esqueça a
key
propriedade.fonte
Usando mapa matriz função é maneira muito comum para fazer um loop através de uma matriz de elementos e criar componentes de acordo com eles em Reagir , esta é uma ótima maneira de fazer um loop que é muito eficiente e forma arrumada para fazer seus loops em JSX , é não a única maneira de fazê-lo, mas a maneira preferida.
Além disso, não se esqueça de ter uma chave exclusiva para cada iteração, conforme necessário. A função de mapa cria um índice exclusivo de 0, mas não é recomendado o uso do índice produzido, mas se seu valor for único ou se houver uma chave exclusiva, você poderá usá-los:
Além disso, poucas linhas do MDN se você não estiver familiarizado com a função de mapa na matriz:
fonte
Array#map
não é assíncrono!Se você já está usando o lodash, a
_.times
função é útil.fonte
Você também pode extrair fora do bloco de retorno:
fonte
Sei que esse é um encadeamento antigo, mas você pode fazer o checkout de React Templates , que permite usar modelos no estilo jsx em react, com algumas diretivas (como rt-repeat).
Seu exemplo, se você usasse reag-templates, seria:
fonte
Existem várias maneiras de fazer isso. O JSX eventualmente é compilado para JavaScript; portanto, enquanto você estiver escrevendo JavaScript válido, será bom.
Minha resposta tem como objetivo consolidar todas as formas maravilhosas já apresentadas aqui:
Se você não possui uma matriz de objeto, basta o número de linhas:
dentro do
return
bloco, criandoArray
e usandoArray.prototype.map
:fora do
return
bloco, basta usar um loop for JavaScript normal:expressão de função invocada imediatamente:
Se você tiver uma matriz de objetos
dentro do
return
bloco,.map()
cada objeto em um<ObjectRow>
componente:fora do
return
bloco, basta usar um loop for JavaScript normal:expressão de função invocada imediatamente:
fonte
se numrows é uma matriz, e é muito simples.
O tipo de dados do array no React é muito melhor, o array pode fazer backup de um novo array e oferecer suporte a filtros, reduzir etc.
fonte
Existem várias respostas apontando para o uso da
map
declaração. Aqui está um exemplo completo usando um iterador dentro do componente FeatureList para listar os componentes do recurso com base em uma estrutura de dados JSON denominada features .Você pode visualizar o código completo do FeatureList no GitHub. O dispositivo elétrico de recursos está listado aqui .
fonte
Para repetir várias vezes e retornar, você pode obtê-lo com a ajuda de
from
emap
:Onde
i = number of times
Se você deseja atribuir IDs de chave exclusivos aos componentes renderizados, pode usar
React.Children.toArray
conforme proposto na documentação do ReactReact.Children.toArray
Retorna a estrutura de dados opaca filhos como uma matriz plana com chaves atribuídas a cada filho. Útil se você deseja manipular coleções de filhos em seus métodos de renderização, especialmente se deseja reordenar ou cortar this.props.children antes de transmiti-lo.
fonte
Se você optar por converter esse método return () interno do método render , a opção mais fácil seria usar o método map () . Mapeie sua matriz na sintaxe JSX usando a função map (), como mostrado abaixo (a sintaxe ES6 é usada ).
Componente pai interno :
Observe o
key
atributo adicionado ao seu componente filho. Se você não forneceu um atributo-chave, poderá ver o seguinte aviso no console.Nota: Um erro comum que as pessoas cometem é usar
index
como chave ao iterar, usarindex
o elemento como chave é um antipadrão e você pode ler mais sobre isso aqui . Em resumo, se NÃO for uma lista estática, nunca useindex
como chave.Agora, no componente ObjectRow , você pode acessar o objeto a partir de suas propriedades.
Componente Inside ObjectRow
const { object } = this.props
ou
const object = this.props.object
Isso deve buscar o objeto que você passou do componente pai para a variável
object
no componente ObjectRow . Agora você pode cuspir os valores nesse objeto de acordo com o seu propósito.Referências :
método map () em Javascript
Script ECMA 6 ou ES6
fonte
digamos que temos uma variedade de itens em seu estado:
fonte
Uma possibilidade do ES2015 / Babel está usando uma função de gerador para criar uma matriz de JSX:
fonte
... Ou você também pode preparar uma matriz de objetos e mapeá-la para uma função para obter a saída desejada. Eu prefiro isso, porque me ajuda a manter as boas práticas de codificação sem lógica dentro do retorno da renderização.
fonte
Basta usar
.map()
para percorrer sua coleção e retornar<ObjectRow>
itens com acessórios de cada iteração.Assumindo que
objects
há uma matriz em algum lugar ...fonte
ES2015 Array.from com a função de mapa + tecla
Se você não tem nada,
.map()
pode usarArray.from()
com amap
função para repetir elementos:fonte
Eu uso isso:
PS: nunca esqueça a chave ou você terá muitos avisos!
fonte
.Id
propriedade, comoitems.map( (item, index) => <Foo key={index}>{item}</Foo>
Eu tendem a favorecer uma abordagem em que a lógica de programação acontece fora do valor de retorno de
render
. Isso ajuda a manter fácil o que realmente é renderizado.Então eu provavelmente faria algo como:
É certo que essa é uma quantidade tão pequena de código que, se for embutida, pode funcionar bem.
fonte
import { map } from 'lodash'
que você não importasse todas as funções do lodash, se você não precisar delas.map()
, apenas matrizes. Era isso que eu estava dizendo que o lodash é bom para fazer um loop sobre um objeto.objects
como em uma lista de coisas, meu erro.é claro que você pode resolver com um .map, conforme sugerido pela outra resposta. Se você já usa o babel, pode pensar em usar jsx-control-statement. Eles exigem um pouco de configuração, mas acho que vale a pena em termos de legibilidade (especialmente para desenvolvedores que não reagem). Se você usa um linter, também há instruções eslint-plugin-jsx-control-instructions
fonte
Seu código JSX será compilado em código JavaScript puro. Todas as tags serão substituídas por
ReactElement
objetos. Em JavaScript, você não pode chamar uma função várias vezes para coletar suas variáveis retornadas.É ilegal, a única maneira é usar uma matriz para armazenar as variáveis retornadas pela função.
Ou você pode usar o
Array.prototype.map
que está disponível desde o JavaScript ES5 para lidar com essa situação.Talvez possamos escrever outro compilador para recriar uma nova sintaxe JSX para implementar uma função de repetição, como a do Angular
ng-repeat
.fonte
Isso pode ser feito de várias maneiras.
return
armazenar todos os elementos na matrizLoop dentro
return
Método 1
Método 2
fonte
Aqui está uma solução simples para isso.
Nenhum mapeamento e código complexo são necessários. Você só precisa enviar as linhas para a matriz e retornar os valores para renderizá-la.
fonte
Como você está escrevendo a sintaxe Javascript no código JSX, é necessário agrupar seu Javascript entre chaves.
fonte
Aqui está um exemplo do React doc: Expressões JavaScript como Filhos
como seu caso, sugiro escrever assim:
Observe que a chave é muito importante, porque o React usa a chave para diferenciar os dados na matriz.
fonte
Eu uso assim
fonte
Você pode fazer algo como:
fonte
Ótima pergunta.
O que faço quando quero adicionar um certo número de componentes é usar uma função auxiliar.
Defina uma função que retorne JSX:
fonte
Você também pode usar uma função de auto-chamada:
fonte