Beruflich Dokumente
Kultur Dokumente
Prueba React
Aprende React
Mantente Informado
Documentación por Versiones
¿Algo hace falta?
Prueba React
React ha sido diseñado desde su inicio para ser adoptado gradualmente, así
puedes usar tan poco o mucho de React como necesites. Si quieres una
prueba de React, agregar interactividad a una simple página HTML o
empezar una aplicación compleja con React, los enlaces de esta sección te
ayudarán a empezar.
Área de juegos
Si estás interesado en jugar un poco con React, puedes usar un editor de
código online. Prueba la plantilla “Hola mundo”
en CodePen, CodeSandbox o Glitch.
Si prefieres usar tu propio editor, también puedes descargar este archivo
HTML, editarlo, y abrirlo desde tu sistema de archivos al navegador. Esto
realiza una transformación de código lenta, así que solo recomendamos esto
para pruebas simples.
Agregar React a un sitio web.
Puedes agregar React a un HTML en un minuto. Puedes o bien ir
agregándolo gradualmente, o mantenerlo contenido en unos
cuantos widgets dinámicos.
Crea una aplicación React nueva
Cuando se empieza un proyecto con React, una simple página HTML con
una etiqueta de tiposcript puede ser la mejor opción. Solo toma un minuto
para configurarse.
A medida que tu aplicación crezca, puede que consideres una configuración
más integrada. Hay una gran variedad de herramientas que recomendamos
para aplicaciones más grandes. Cada una de ellas puede funcionar con poca
configuración, y te permite tomar toda la ventaja de un ambiente React
completo.
Aprende React
Las personas vienen a React de distintos orígenes y de diferentes estilos de
aprendizaje. Si prefieres un enfoque más teórico o práctico, esperamos que
encuentres esta sección útil.
Si prefieres aprender mediante práctica, empieza con nuestro tutorial práctico.
Si prefieres aprender los conceptos paso a paso, empieza con nuestra guía a los
conceptos principales.
Como cualquier tecnología desconocida, React tiene una curva de
aprendizaje. Con práctica y un poco de paciencia, obtendrás habilidad sobre
esta.
Primeros ejemplos
La página principal de React tiene unos cuantos ejemplos pequeños de
React con un editor en vivo. Incluso si no sabes nada de React aún, prueba
cambiando el código y mira cómo afecta el resultado.
React para principiantes
Si sientes que la documentación de React va a un ritmo mayor del que te
sientes cómodo, mira este resumen de React por Tania Rascia. Introduce los
conceptos más importantes de React de una forma más detallada y amigable
para los principiantes. Una vez que lo termines, intenta leer la
documentación de nuevo.
React para diseñadores
Si vienes con experiencia como diseñador, estos recursos son un gran lugar
para empezar.
Recursos JavaScript
La documentación de React asume cierta familiaridad con la programación
en Javascript. No necesitas ser un experto, pero es más difícil aprender React
y Javascript al mismo tiempo.
Recomendamos pasar por este resumen de Javascript para medir tu nivel de
conocimiento. Te tomará entre treinta minutos y una hora, pero te sentirás
más seguro aprendiendo React.
Consejo
Cuando te sientas confundido sobre algo de
Javascript, MDN y javascript.info son sitios increíbles para revisar. También
hay un foro de asistencia por la comunidad donde puedes pedir ayuda.
Tutorial práctico
Si prefieres aprender mediante práctica, mira nuestro tutorial práctico. En
este tutorial construimos el juego tres en raya en React. Puede que te sientas
tentado a saltártelo porque no desarrollas juegos, pero dale una
oportunidad. Las técnicas que aprenderás en el tutorial son fundamentales
para desarrollar cualquier aplicación con React, y dominarlas te dará un
entendimiento mucho más profundo.
Guía paso a paso
Si prefieres aprender los conceptos paso a paso, nuestra guía a los
conceptos principales es el mejor lugar para empezar. Cada capítulo en ella
parte del conocimiento introducido en capítulos anteriores, por lo que no te
perderás nada a medida que avanzas.
Pensando en React
Muchos usuarios de React dan crédito a leer Pensando en React como el
momento en el que React finalmente tuvo “sentido” para ellos. Es
probablemente el paso a paso más viejo, pero aún es igual de relevante.
Cursos recomendados
A veces las personas consiguen libros de terceros o recursos de video más
útiles que la misma documentación. Mantenemos una lista de recursos
usualmente recomendados, algunos de ellos son gratis.
Conceptos avanzados
Una vez que te sientas cómodo con los conceptos principales y hayas jugado
con React un poco, puede que estés interesado en temas más avanzados.
Esta sección te presentará funcionalidades poderosas, pero menos conocidas
de React como contexto o referencias.
Referencia de la API
Esta sección de la documentación es útil si quieres aprender detalles sobre
una API de React en específico. Por ejemplo, la referencia de
React.Component te puede dar detalles en cómo funciona setState(), y para
qué sirven diferentes métodos del ciclo de vida del componente.
Glosario y preguntas frecuentes
El glosario contiene un resumen de los términos más comunes que verás en
la documentación de React. También hay una sección de preguntas
frecuentes dedicada a preguntas cortas y respuestas sobre temas comunes,
incluyendo realizar solicitudes con AJAX, estado de un componente,
y estructura de archivos.
Mantente informado
El Blog de React es la fuente oficial de actualizaciones por parte del equipo
de React. Cualquier información importante, incluyendo notas sobre
lanzamientos o notas de depreciación, serán puestas allí primero.
También puedes seguir la cuenta de @reactjs en Twitter, pero no te perderás
de nada esencial si solo lees el blog.
No todos los lanzamientos de React ameritan su propia publicación en el
blog, pero puedes encontrar una lista detallada de cambios para cada
lanzamiento en el archivo CHANGELOG.MD en el repositorio de React, así
como también en la página de Lanzamientos.
Agregar React a un
sitio web
Utiliza sólo lo que necesites de React.
React fue diseñado desde el principio para que se pudiera adoptar de forma
gradual, y puedas utilizar sólo las cosas que necesites de React. Quizás
solo quieras agregar una “pizca de interactividad” a una página existente. Los
componentes de React son una gran manera de hacer eso.
La mayoría de sitios web no son, y no necesitan ser, aplicaciones de una sóla
página. Con unas pocas líneas de código y sin herramientas de
compilación, puedes probar React en lugares pequeños de tu sitio web. Y
de allí puedes expandir su presencia de forma gradual, o mantenerlo
contenido a unos pocos en unos widgets dinámicos.
<div id="like_button_container"></div>
Las primeras dos etiquetas cargan React. La tercera carga tu código del
componente.
Paso 3: Crea un componente de React
Crea un archivo llamado like_button.js en el mismo lugar donde tienes tu
archivo HTML.
Abre este código inicial y pégalo en el archivo que acabaste de crear.
Consejo
Este código define un componente de React llamado LikeButton. No te
preocupes si aún no lo entiendes — vamos a cubrir los elementos básicos de
React luego en nuestro tutorial práctico y guía de conceptos principal. Por
ahora, ¡vamos a hacer que se muestre en la pantalla!
Después en el código inicial, agrega las siguientes dos lineas al final
de like_button.js:
// ... el código inicial que pegaste ...
Dale un vistazo a las siguientes secciones para más consejos sobre como
integrar React.
Mira el código fuente del ejemplo completo
Descargar el ejemplo completo (2KB comprimido)
Consejo: Reusar un componente
Por lo general, es deseado mostrar componentes de React en múltiples
lugares de una página HTML. Aquí hay un ejemplo que muestra el botón de
“Like” tres veces y le pasa algunos datos al mismo:
Mira el código fuente del ejemplo completo
Descargar el ejemplo completo (2KB comprimido)
Nota
Esta estrategía es útil cuando las partes de la página que funcionan en React
están aisladas entre sí. En código de React, es mucho más fácil
usar composición de componentes en su lugar.
Si no tienes un paso para compactar tus scripts, aquí hay una forma en que
puedes establecerlo.
Nota
npx no es un error de escritura — es una herramienta de ejecución de
paquetes incluida en npm 5.2+.
Si ves algún mensaje de error que te dice que “Has instalado
equivocadamente el paquete de babel”, puede ser que olvidaste realizar el
paso anterior. Realiza el paso anterior en la misma carpeta en que estás y
vuelve a intentar este paso.
Cadenas de herramientas
recomendadas
El equipo de React principalmente recomienda las siguientes soluciones:
Si estás aprendiendo React o creando una nueva aplicación de página
única, usa Create React App.
Si estás construyendo un sito web renderizado en servidor con
Node.js, prueba Next.js.
Si estás construyendo un sitio web orientado a contenido
estático, prueba Gatsby.
Si estás construyendo una biblioteca de componentes o integrando una base de
código existente, prueba Cadenas de Herramientas más Flexibles.
Create React App
Create React App es un ambiente cómodo para aprender React, y es la
mejor manera de comenzar a construir una nueva aplicación de página
única usando React.
Create React App configura tu ambiente de desarrollo de forma que puedas
usar las últimas características de Javascript, brindando una buena
experiencia de desarrollo, y optimizando tu aplicación para producción.
Necesitarás tener Node >= 8.10 y npm >= 5.6 instalados en tu máquina.
Para crear un proyecto ejecuta:
npx create-react-app my-app
cd my-app
npm start
Nota
En la primera línea npx no es un error de escritura: Es una herramienta de
ejecución de paquetes que viene con npm 5.2+.
Create React App no se encarga de la lógica de backend o de bases de datos;
tan solo crea un flujo de construcción para frontend, de manera que lo
puedes usar con cualquier backend. Para ello internamente
usa Babel y webpack, pero no necesitas saber nada de estas herramientas
para usar Create React App.
Cuando estés listo para desplegar a producción, ejecuta npm run build lo cual
crea una compilación optimizada de tu aplicación en el directorio build.
Puedes aprender más acerca de Create React App en su archivo README y
en la Guía del Usuario.
Next.js
Next.js es un framework popular y ligero para aplicaciones estáticas y
renderizadas en servidor construidas con React. Integra soluciones de
estilo y enrutamiento y asume que estás usando Node.js como ambiente
de servidor.
Aprende Next.js de su guía oficial.
Gatsby
Gatsby es la mejor manera de crear sitios web estáticos usando React. Te
permite usar componentes React, pero genera HTML y CSS pre-renderizado
para garantizar el tiempo de carga más rápido.
Aprende Gatsby de su guía oficial y de la galería de kits de inicio.
Cadenas de herramientas más flexibles
Las siguientes cadenas de herramientas ofrecen más opciones y flexibilidad.
Las recomendamos para los usuarios con más experiencia:
Neutrino combina el poder de webpack con la simplicidad de
los presets (configuraciones preempaquetadas), e incluye presets para aplicaciones
React y componentes React.
nwb es particularmente bueno para publicar componentes React en npm. También
puede ser usado para crear aplicaciones React.
Parcel es un empaquetador de aplicaciones web rápido y de cero configuración
que funciona con React.
Razzle es un framework de renderizado en servidor que no requiere ninguna
configuración, pero ofrece más flexibilidad que Next.js.
Enlaces CDN
Ambos React y ReactDOM están disponibles a través
de un CDN.
<script crossorigin
src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-
dom.development.js"></script>
CONCEPTOS FUNDAMENTALES
Hola mundo
El más pequeño de los ejemplos de React se ve así:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
Este es el primer capítulo en una guía paso a paso sobre los principales
conceptos de React. Puedes encontrar una lista de todos los capítulos en la
barra de navegación lateral. Si estás leyendo esto desde un dispositivo móvil,
puedes acceder a la navegación presionando el botón en la esquina inferior
derecha de tu pantalla.
Cada capítulo en esta guía se construye en base al conocimiento presentado
en capítulos anteriores. Puedes aprender la mayoría de React leyendo la
guía de conceptos “Conceptos Principales” en el orden que aparecen en
la barra lateral. Por ejemplo, “Introducción a JSX”es el siguiente capítulo
después de este.
Empecemos!
Sigue bajando, y encontrarás el link al siguiente capítulo de esta guía justo
antes del pie de la página.
Edita esta página
Presentando JSX
Considera la declaración de esta variable:
const element = <h1>Hello, world!</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
Puedes poner cualquier expresión de JavaScript dentro de llaves en JSX. Por
ejemplo, 2 + 2, user.firstName, o formatName(user) son todas expresiones
válidas de Javascript.
En el ejemplo a continuación, insertamos el resultado de llamar la función de
JavaScript, formatName(user), dentro de un elemento <h1>.
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
};
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
ReactDOM.render(
element,
document.getElementById('root')
);
Pruébalo en CodePen
Dividimos JSX en varias líneas para facilitar la lectura. Aunque no es
necesario, cuando hagas esto también te recomendamos envolverlo entre
paréntesis para evitar errores por la inserción automática del punto y coma.
JSX también es una expresión
Después de compilarse, las expresiones JSX se convierten en llamadas a
funciones JavaScript regulares y se evalúan en objetos JavaScript.
Esto significa que puedes usar JSX dentro de declaraciones if y bucles for,
asignarlo a variables, aceptarlo como argumento, y retornarlo desde dentro
de funciones:
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
Renderizando
elementos
Los elementos son los bloques más pequeños de las
aplicaciones de React.
Renderizando un elemento en el
DOM
Digamos que hay un <div> en alguna parte de tu archivo HTML:
<div id="root"></div>
setInterval(tick, 1000);
Pruébalo en CodePen
Este llama a ReactDOM.render() cada segundo desde un callback
del setInterval().
Nota:
En la práctica, la mayoría de las aplicaciones de React solo
llama ReactDOM.render() una vez. En las siguientes secciones aprenderemos
cómo el código se puede encapsular en componentes con estado.
Componentes funcionales y de
clase
La forma más sencilla de definir un componente es escribir una función de
JavaScript:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
Renderizando un componente
Anteriormente, sólo encontramos elementos de React que representan las
etiquetas del DOM:
const element = <div />;
Pruébalo en CodePen
Composición de componentes
Los componentes pueden referirse a otros componentes en su salida. Esto
nos permite utilizar la misma abstracción de componente para cualquier
nivel de detalle. Un botón, un cuadro de diálogo, un formulario, una pantalla:
en aplicaciones de React, todos son expresados comúnmente como
componentes.
Por ejemplo, podemos crear un componente App que
renderiza Welcome muchas veces:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Pruébalo en CodePen
Por lo general, las aplicaciones de React nuevas tienen un único
componente App en lo más alto. Sin embargo, si se integra React en una
aplicación existente, se podría empezar de abajo hacia arriba con un
pequeño componente como Button y poco a poco trabajar el camino a la
cima de la jerarquía de la vista.
Extracción de componentes
No tengas miedo de dividir los componentes en otros más pequeños.
Por ejemplo, considera este componente Comment:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
Pruébalo en CodePen
Acepta author (un objeto), text (un string), y date (una fecha) como props, y
describe un comentario en una web de redes sociales.
Este componente puede ser difícil de cambiar debido a todo el anidamiento,
y también es difícil reutilizar partes individuales de él. Vamos a extraer
algunos componentes del mismo.
Primero, vamos a extraer Avatar:
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
Pruébalo en CodePen
Extraer componentes puede parecer un trabajo pesado al principio, pero
tener una paleta de componentes reutilizables vale la pena en aplicaciones
más grandes. Una buena regla en general es que si una parte de su interfaz
de usuario se usa varias veces (Button, Panel, Avatar), o es lo suficientemente
compleja por sí misma (App, FeedStory, Comment), es buen candidato para ser un
componente reutilizable.
setInterval(tick, 1000);
Pruébalo en CodePen
En esta sección, aprenderemos como hacer al
componente Clock verdaderamente reutilizable y encapsulado. Configurarás
tu propio temporizador y se actualizará cada segundo.
function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('root')
);
}
setInterval(tick, 1000);
Pruébalo en CodePen
Sin embargo, se pierde un requisito crucial: el hecho de que Clock configure
un temporizador y actualice la interfaz de usuario cada segundo debe ser un
detalle de implementación de Clock.
Idealmente, queremos escribir esto una vez y que Clock se actualice a sí
mismo:
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
Pruébalo en CodePen
Clock ahora se define como una clase en lugar de una función.
El método render se invocará cada vez que ocurre una actualización; pero,
siempre y cuando rendericemos <Clock /> en el mismo nodo del DOM, se
usará solo una única instancia de la clase Clock. Esto nos permite utilizar
características adicionales como el estado local y los métodos de ciclo de
vida.
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
El resultado es el siguiente:
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
Pruébalo en CodePen
A continuación, haremos que Clock configure su propio temporizador y se
actualice cada segundo.
componentDidMount() {
componentWillUnmount() {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
Pruébalo en CodePen
Para arreglarlo, usa una segunda forma de setState() que acepta una función
en lugar de un objeto. Esa función recibirá el estado previo como primer
argumento, y las props en el momento en que se aplica la actualización
como segundo argumento:
// Correcto
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
fetchComments().then(response => {
this.setState({
comments: response.comments
});
});
}
Pruébalo en CodePen
ReactDOM.render(
<App />,
document.getElementById('root')
);
Pruébalo en CodePen
Cada Clock configura su propio temporizador y se actualiza de forma
independiente.
Manejando eventos
Manejar eventos en elementos de React es muy similar
a manejar eventos con elementos del DOM. Hay
algunas diferencias de sintaxis:
Los eventos de React se nombran usando camelCase, en vez de minúsculas.
Con JSX pasas una función como el manejador del evento, en vez de un string.
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
Pruébalo en CodePen
Tienes que tener mucho cuidado en cuanto al significado de this en los
callbacks de JSX. En JavaScript, los métodos de clase no están ligados por
defecto. Si olvidas ligar this.handleClick y lo pasas
a onClick, this será undefined cuando se llame la función.
Esto no es un comportamiento especifico de React; esto hace parte de como
operan las funciones JavaScript. Generalmente, si refieres un método sin
usar () después de este, tal como onClick={this.handleClick}, deberías
ligar ese método.
Si te molesta llamar bind, existen dos maneras de evitarlo. Si usas la sintaxis
experimental campos públicos de clases, puedes usar los campos de clases
para ligar los callbacks correctamente:
class LoggingButton extends React.Component {
// Esta sintaxis nos asegura que `this` está ligado dentro de handleClick
// Peligro: esto es una sintaxis *experimental*
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
render() {
// Esta sintaxis nos asegura que `this` esta ligado dentro de
handleClick
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
El problema con esta sintaxis es que un callback diferente es creado cada vez
que LogginButton es renderizado. En la mayoría de los casos, esto está bien.
Sin embargo, si este callback se pasa como una propiedad a componentes
más bajos, estos componentes podrían renderizarse nuevamente.
Generalmente, recomendamos ligar en el constructor o usar la sintaxis de
campos de clases, para evitar esta clase de problemas de rendimiento.
Pasando argumentos a
escuchadores de eventos
Dentro de un bucle es muy común querer pasar un parámetro extra a un
manejador de eventos. Por ejemplo, si id es el ID de una fila, cualquiera de
los códigos a continuación podría funcionar:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
Renderizado
condicional
En React, puedes crear distintos componentes que
encapsulan el comportamiento que necesitas.
Entonces, puedes renderizar solamente algunos de
ellos, dependiendo del estado de tu aplicación.
El renderizado condicional en React funciona de la misma forma que lo
hacen las condiciones en JavaScript. Usa operadores de JavaScript como if o
el operador condicional para crear elementos representando el estado
actual, y deja que React actualice la interfaz de usuario para emparejarlos.
Considera estos dos componentes:
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
Vamos a crear un componente Greeting que muestra cualquiera de estos
componentes dependiendo si el usuario ha iniciado sesión:
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
// Intentar cambiando isLoggedIn={true}:
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
Pruébalo en CodePen
Este ejemplo renderiza un saludo diferente según el valor del prop isLoggedIn.
Variables de elementos
Puedes usar variables para almacenar elementos. Esto puede ayudarte para
renderizar condicionalmente una parte del componente mientras el resto del
resultado no cambia.
ReactDOM.render(
<Page />,
document.getElementById('root')
);
Pruébalo en CodePen
El devolver null desde el método render de un componente no influye en la
activación de los métodos del ciclo de vida del componente. Por
ejemplo componentDidUpdate seguirá siendo llamado.
Edita esta página
Listas y keys
Primero, vamos a revisar como transformas listas en
Javascript.
Dado el código de abajo, usamos la función map() para tomar un array
de numbers y duplicar sus valores. Asignamos el nuevo array devuelto
por map() a la variable doubled y la mostramos:
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);
Este código muestra [2, 4, 6, 8, 10] a la consola.
En React, transformar arrays en listas de elementos es casi idéntico.
Renderizado de Múltiples Componentes
Puedes hacer colecciones de elementos e incluirlos en JSX usando llaves {}.
Debajo, recorreremos el array numbers usando la función map() de Javascript.
Devolvemos un elemento <li> por cada ítem . Finalmente, asignamos el array
de elementos resultante a listItems:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li>{number}</li>
);
Incluimos entero el array listItems dentro de un elemento <ul>, y lo
renderizamos al DOM:
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
Pruébalo en CodePen
Cuando ejecutes este código, serás advertido que una key debería ser
proporcionada para ítems de lista. Una “key” es un atributo especial string
que debes incluir al crear listas de elementos. Vamos a discutir por qué esto
es importante en la próxima sección.
Vamos a asignar una key a nuestra lista de ítems dentro de numbers.map() y
arreglar el problema de la falta de key.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
Keys
Las keys ayudan a React a identificar que ítems han cambiado, son
agregados, o son eliminados. Las keys deben ser dadas a los elementos
dentro del array para darle a los elementos una identidad estable:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
Cuando no tengas IDs estables para renderizar, puedes usar el índice del
ítem como una key como último recurso:
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
No recomendamos usar índices para keys si el orden de los ítems puede
cambiar. Esto puede impactar negativamente el rendimiento y puede causar
problemas con el estado del componente. Revisa el artículo de Robin
Pokorny para una explicación en profundidad de los impactos negativos de
usar un índice como key. Si eliges no asignar una key explícita a la lista de
ítems, React por defecto usará índices como keys.
Aquí hay una explicación en profundidad sobre por qué las keys son
necesarias si estás interesado en aprender más.
Extracción de componentes con keys
Las keys solo tienen sentido en el contexto del array que las envuelve.
Por ejemplo, si extraes un componente ListItem, deberías mantener la key en
los elementos <ListItem /> del array en lugar de en el elemento <li> del
propio ListItem.
Ejemplo: Uso Incorrecto de Key
function ListItem(props) {
const value = props.value;
return (
// Mal! No hay necesidad de especificar la key aquí:
<li key={value.toString()}>
{value}
</li>
);
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Mal! La key debería haber sido especificada aquí:
<ListItem value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Correcto! La key debería ser especificada dentro del array.
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const posts = [
{id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
{id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
<Blog posts={posts} />,
document.getElementById('root')
);
Pruébalo en CodePen
Las keys sirven como una sugerencia para React pero no son pasadas a tus
componentes. Si necesitas usar el mismo valor en tu componente, pásasela
explícitamente como una propiedad con un nombre diferente:
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);
Con el ejemplo de arriba, el componente Post puede leer props.id, pero
no props.key.
Integrar map() en JSX
En los ejemplos de arriba declaramos una variable separada listItems y la
incluimos en JSX:
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
JSX permite integrar cualquier expresión en llaves así que podemos alinear el
resultado de map():
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
</ul>
);
}
Pruébalo en CodePen
Algunas veces esto resulta más claro en código, pero este estilo también
puede ser abusado. Como en JavaScript, depende de ti decidir cuando vale
la pena extraer una variable por legibilidad. Ten en mente que si el cuerpo
de map() está muy anidado, puede ser un buen momento para extraer un
componente.
Edita esta página
Formularios
Los elementos de formularios en HTML funcionan un
poco diferente a otros elementos del DOM en React,
debido a que los elementos de formularios conservan
naturalmente algún estado interno. Por ejemplo, este
formulario solamente en HTML, acepta un solo
nombre.
<form>
<label>
Name:
<input type="text" name="name" />
</label>
<input type="submit" value="Submit" />
</form>
Componentes controlados
En HTML, los elementos de formularios como los <input>, <textarea> y
el <select>normalmente mantienen sus propios estados y los actualizan de
acuerdo a la interacción del usuario. En React, el estado mutable es
mantenido normalmente en la propiedad estado de los componentes, y solo
se actualiza con setState().
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value}
onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Pruébalo en CodePen
Ya que el atributo value es agregado en nuestro elemento del formulario, el
valor mostrado siempre será el de this.state.value, haciendo que el estado
de React sea la fuente de la verdad. Ya que handleChange corre cada vez que
una tecla es oprimida para actualizar el estado de React, el valor mostrado
será actualizado mientras que el usuario escribe.
Con un componente controlado, toda mutación del estado tendrá asociada
una función controlador. Esto hace más directo modificar o validar la entrada
del usuario. Por ejemplo, si quisiéramos asegurar que los nombres sean
escritos con todas las letras en mayúscula, podríamos escribir
el handleChange como:
handleChange(event) {
this.setState({value: event.target.value.toUpperCase()});
}
La etiqueta textarea
En HTML, el elemento <textarea> define su texto por sus hijos:
<textarea>
Hello there, this is some text in a text area
</textarea>
En React, un <textarea> utiliza un atributo value en su lugar. De esta manera,
un formulario que hace uso de un <textarea> puede ser escrito de manera
similar a un formulario que utiliza un campo en una sola línea:
class EssayForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'Please write an essay about your favorite DOM element.'
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('An essay was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Essay:
<textarea value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Recuerda que this.state.value es inicializado en el constructor, de manera
que el área de texto empiece con algo de texto.
La etiqueta select
En HTML, <select> crea una lista desplegable. Por ejemplo, este HTML crea
una lista desplegable de sabores:
<select>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option selected value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
Ten en cuenta que la opción Coco es inicialmente seleccionada, debido al
atributo selected. React, en lugar de utilizar el atributo selected, utiliza un
atributo value en la raíz de la etiqueta select. Esto es más conveniente en un
componente controlado debido a que solo necesitas actualizarlo en un solo
lugar, por ejemplo:
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Pruébalo en CodePen
En resumen, esto hace que <input type="text">, <textarea>, y <select> trabajen
de manera similar, todos aceptan un atributo value el cual puedes usar para
implementar un componente controlado.
Nota
Puedes pasar un array al atributo value, permitiendo que selecciones
múltiples opciones en una etiqueta select:
<select multiple={true} value={['B', 'C']}>
Por ejemplo:
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked :
target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
Pruébalo en CodePen
Ten en cuenta como utilizamos la sintaxis de la propiedad name computada
de ES6 para actualizar la clave del estado correspondiente al nombre
del input.
this.setState({
[name]: value
});
setTimeout(function() {
ReactDOM.render(<input value={null} />, mountNode);
}, 1000);
Alternativas a componentes
controlados
A veces puede ser tedioso usar componentes controlados, debido a que se
necesita escribir un controlador de eventos para cada forma en la que tus
datos puedan cambiar y agregarlos a todos en el estado del input a través
del componente React. Esto puede volverse particularmente molesto cuando
estás convirtiendo una base de código existente a React, o integrando una
aplicación React con una biblioteca que no integra React. En estas
situaciones, puede que quieras leer acerca de componentes no controlados,
una técnica alternativa para implementar inputs en formularios.
Soluciones completas
Si lo que estás buscando es una solución completa incluyendo validación,
tener en cuenta los campos visitados y manejar el envío del
formulario, Formik es una de las opciones populares. Sin embargo, está
construido con los mismos principios de los componentes controlados y
manejo de estado, así que no los dejes de aprender.
Edita esta página