Estoy tratando de hacer algo como lo siguiente en React JSX
(donde ObjectRow es un componente separado):
<tbody>
for (var i=0; i < numrows; i++) {
<ObjectRow/>
}
</tbody>
Me doy cuenta y entiendo por qué esto no es válido JSX
, ya que se JSX
asigna a llamadas a funciones. Sin embargo, viniendo de la plantilla y siendo nuevo en JSX
, no estoy seguro de cómo lograría lo anterior (agregando un componente varias veces).
javascript
reactjs
Ben Roberts
fuente
fuente
let todos = this.props.todos.map((todo) => {return <h1>{todo.title}</h1>})
let todos = this.props.todos.map(t => <h1>{t.title}</h1>)
:)Respuestas:
Piense en ello como si solo estuviera llamando a funciones de JavaScript. No puede usar un
for
bucle donde irían los argumentos de una llamada a la función:Vea cómo
tbody
se pasa unfor
bucle a la función como argumento y, por supuesto, es un error de sintaxis.Pero puede hacer una matriz y luego pasarla como argumento:
Puedes usar básicamente la misma estructura cuando trabajas con JSX:
Por cierto, mi ejemplo de JavaScript es casi exactamente en lo que se transforma ese ejemplo de JSX. Juega con Babel REPL para tener una idea de cómo funciona JSX.
fuente
map
(por ejemplo, no tiene una colección almacenada en una variable).key
a cada niño. REF: facebook.github.io/react/docs/…key
propiedad y también un estilo de código que realmente no se usa en las bases de código React. Considere esta respuesta stackoverflow.com/questions/22876978/loop-inside-react-jsx/… como correcta.No estoy seguro si esto funcionará para su situación, pero a menudo el mapa es una buena respuesta.
Si este fue su código con el bucle for:
Podrías escribirlo así con el mapa :
Sintaxis ES6:
fuente
<tbody>{objects.map((o, i) => <ObjectRow obj={o} key={i}/>}</tbody>
usando el soporte ES6 de Reactify o 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]} />)
Si aún no tiene una matriz que le
map()
guste la respuesta de @ FakeRainBrigand, y desea alinear esto para que el diseño de origen corresponda a la salida más cercana que la respuesta de @ SophieAlpert:Con sintaxis ES2015 (ES6) (funciones de dispersión y flecha)
http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview
Re: transpilando con Babel, su página de advertencias dice que
Array.from
se requiere para la propagación, pero en la actualidad (v5.8.23
) ese no parece ser el caso cuando se difunde un realArray
. Tengo un problema de documentación abierto para aclarar eso. Pero use bajo su propio riesgo o polyfill.Vanilla ES5
Array.apply
IIFE en línea
http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview
Combinación de técnicas de otras respuestas.
Mantenga el diseño de origen correspondiente a la salida, pero haga que la parte en línea sea más compacta:
Con sintaxis y
Array
métodos ES2015Con
Array.prototype.fill
usted podría hacer esto como una alternativa al uso de propagación como se ilustra arriba:(Creo que podría omitir cualquier argumento
fill()
, pero no estoy al 100% en eso). Gracias a @FakeRainBrigand por corregir mi error en una versión anterior de lafill()
solución (ver revisiones).key
En todos los casos, el
key
atributo alivia una advertencia con la construcción de desarrollo, pero no es accesible en el niño. Puede pasar un atributo adicional si desea que el índice esté disponible en el elemento secundario. Ver Listas y claves para la discusión.fuente
yield
? Insertar elementos en una matriz intermedia es algo feo cuando tenemos generadores. ¿Funcionan?[...Array(x)].map(() => <El />))
versión, que creo que es la más elegante, y por qué lo presenté. Re: la segunda pregunta, ese es un gran punto. No parece haber nada acerca de JSX que lo impida, por lo que depende de lo que React u otro consumidor de JSX transformado haga con los argumentos secundarios, lo que no podría decir sin mirar la fuente. ¿Tú sabes? Es una pregunta intrigante.fill()
. Ahora recuerdo que la razón por la que dudé es una pregunta acerca de cómo se indica la opcionalidad de los parámetros en la especificación ES (tengo que analizar eso en algún momento). La coma es solo una forma de eludir un elemento de matriz, en este caso el primero. Puede hacerlo si desea que los índices sean de 1..length de la matriz que está distribuyendo en lugar de 0..length-1 de la matriz de propagación (porque los elementos elididos solo contribuyen a la longitud de la matriz y no ' t tiene una propiedad correspondiente).Simplemente usando el método map Array con la sintaxis ES6:
No te olvides de la
key
propiedad.fuente
El uso de la función de mapa Array es una forma muy común de recorrer una matriz de elementos y crear componentes de acuerdo con ellos en React , esta es una excelente manera de hacer un ciclo que es bastante eficiente y ordenada para hacer sus bucles en JSX , no es la única forma de hacerlo, pero la forma preferida.
Además, no olvide tener una clave única para cada iteración según sea necesario. La función de mapa crea un índice único desde 0 pero no se recomienda usar el índice producido, pero si su valor es único o si hay una clave única, puede usarlos:
Además, algunas líneas de MDN si no está familiarizado con la función de mapa en Array:
fuente
Array#map
no es asíncrono!Si ya está usando lodash, la
_.times
función es útil.fuente
También puede extraer fuera del bloque de retorno:
fuente
Sé que este es un hilo antiguo, pero es posible que desee consultar React Templates , que le permite usar plantillas de estilo jsx en react, con algunas directivas (como rt-repeat).
Su ejemplo, si usó react-templates, sería:
fuente
Hay varias formas de hacerlo. JSX finalmente se compila en JavaScript, por lo que siempre que esté escribiendo JavaScript válido, será bueno.
Mi respuesta apunta a consolidar todas las formas maravillosas que ya se presentan aquí:
Si no tiene una matriz de objetos, simplemente el número de filas:
dentro del
return
bloque, creandoArray
y usandoArray.prototype.map
:fuera del
return
bloque, simplemente use un JavaScript for-loop normal:expresión de función invocada inmediatamente:
Si tienes una variedad de objetos
dentro del
return
bloque,.map()
cada objeto a un<ObjectRow>
componente:fuera del
return
bloque, simplemente use un JavaScript for-loop normal:expresión de función invocada inmediatamente:
fuente
if numrows es una matriz, y es muy simple.
El tipo de datos de matriz en React es mucho mejor, la matriz puede respaldar una nueva matriz y admite filtros, reducir, etc.
fuente
Hay varias respuestas que apuntan al uso de la
map
declaración. Aquí hay un ejemplo completo que usa un iterador dentro del componente FeatureList para enumerar los componentes Feature basados en una estructura de datos JSON llamada características .Puede ver el código completo de FeatureList en GitHub. El accesorio de características se enumera aquí .
fuente
Para recorrer varias veces y regresar, puede lograrlo con la ayuda de
from
ymap
:dónde
i = number of times
Si desea asignar ID de clave únicos a los componentes renderizados, puede usarlos
React.Children.toArray
como se propone en la documentación de ReactReact.Children.toArray
Devuelve la estructura de datos opaca de los hijos como una matriz plana con claves asignadas a cada hijo. Útil si desea manipular colecciones de elementos secundarios en sus métodos de representación, especialmente si desea reordenar o dividir this.props.children antes de pasarlo.
fuente
Si se opta para convertir esto dentro de retorno () de rendir método, opción más fácil sería utilizar un mapa () método. Asigne su matriz a la sintaxis JSX usando la función map (), como se muestra a continuación ( se usa la sintaxis ES6 ).
Componente principal interno :
Tenga en cuenta el
key
atributo agregado a su componente hijo. Si no proporcionó un atributo clave, puede ver la siguiente advertencia en su consola.Nota: Un error común que la gente comete es usar
index
como clave al iterar, usarindex
el elemento como clave es un antipatrón y puede leer más sobre esto aquí . En resumen, si NO es una lista estática, nunca la useindex
como clave.Ahora en el componente ObjectRow , puede acceder al objeto desde sus propiedades.
Componente interno de ObjectRow
const { object } = this.props
o
const object = this.props.object
Esto debería obtener el objeto que pasó del componente principal a la variable
object
en el componente ObjectRow . Ahora puede escupir los valores en ese objeto de acuerdo con su propósito.Referencias
método map () en Javascript
ECMA Script 6 o ES6
fuente
digamos que tenemos una variedad de artículos en su estado:
fuente
Una posibilidad de ES2015 / Babel es utilizar una función de generador para crear una matriz de JSX:
fuente
... O también puede preparar una matriz de objetos y asignarla a una función para obtener la salida deseada. Prefiero esto, porque me ayuda a mantener la buena práctica de codificación sin lógica dentro del retorno del render.
fuente
Simplemente use
.map()
para recorrer su colección y devolver<ObjectRow>
artículos con accesorios de cada iteración.Suponiendo que
objects
hay una matriz en alguna parte ...fuente
ES2015 Array.from con la función de mapa + tecla
Si no tiene nada
.map()
que pueda usarArray.from()
con lamap
función para repetir elementos:fuente
Yo uso esto:
PD: ¡nunca olvides la clave o tendrás muchas advertencias!
fuente
.Id
propiedad, comoitems.map( (item, index) => <Foo key={index}>{item}</Foo>
Tiendo a favorecer un enfoque donde la lógica de programación ocurre fuera del valor de retorno de
render
. Esto ayuda a mantener lo que realmente se hace fácil de asimilar.Entonces probablemente haría algo como:
Es cierto que se trata de una cantidad de código tan pequeña que incluirla podría funcionar bien.
fuente
import { map } from 'lodash'
que no esté importando todas las funciones lodash si no las necesita.map()
, solo matrices. Eso es lo que estaba diciendo que lodash es bueno para recorrer un objeto.objects
a una lista de cosas, mi error.por supuesto, puede resolver con un .map como lo sugiere la otra respuesta. Si ya usa babel, podría pensar en usar jsx-control-sentencias. Requieren un poco de configuración, pero creo que vale la pena en términos de legibilidad (especialmente para desarrolladores que no reaccionan). Si usa un linter, también hay eslint-plugin-jsx-control-declaraciones
fuente
Su código JSX se compilará en código JavaScript puro, cualquier etiqueta será reemplazada por
ReactElement
objetos. En JavaScript, no puede llamar a una función varias veces para recopilar sus variables devueltas.Es ilegal, la única forma es usar una matriz para almacenar las variables devueltas de la función.
O puede usar el
Array.prototype.map
que está disponible desde JavaScript ES5 para manejar esta situación.Tal vez podamos escribir otro compilador para recrear una nueva sintaxis JSX para implementar una función de repetición como la de Angular
ng-repeat
.fuente
Esto se puede hacer de múltiples maneras.
return
almacenar todos los elementos en la matrizLazo dentro
return
Método 1
Método 2
fuente
Aquí hay una solución simple para ello.
No se requiere mapeo ni código complejo. Solo necesita empujar las filas a la matriz y devolver los valores para representarlo.
fuente
Como está escribiendo la sintaxis de Javascript dentro del código JSX, debe envolver su Javascript en llaves.
fuente
Aquí hay una muestra de React doc: JavaScript Expressions as Children
según su caso, sugiero escribir así:
Tenga en cuenta que la clave es muy importante, porque React usa la clave para diferenciar los datos en la matriz.
fuente
Lo uso como
fuente
Puedes hacer algo como:
fuente
Gran pregunta
Lo que hago cuando quiero agregar un cierto número de componentes es usar una función auxiliar.
Defina una función que devuelva JSX:
fuente
También puede usar una función de invocación automática:
fuente