Componentes y propiedades
Prueba la nueva documentación de React.
Estas nuevas páginas de la documentación enseñan React moderno e incluyen ejemplos interactivos:
La nueva documentación reemplazará próximamente este sitio, que será archivado. Deja tu opinión aquí
Los componentes permiten separar la interfaz de usuario en piezas independientes, reutilizables y pensar en cada pieza de forma aislada. Esta página proporciona una introducción a la idea de los componentes. Puedes encontrar una API detallada sobre componentes aquí.
Conceptualmente, los componentes son como las funciones de JavaScript. Aceptan entradas arbitrarias (llamadas “props”) y retornan elementos de React que describen lo que debe aparecer en la pantalla.
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>;
}
Esta función es un componente de React válido porque acepta un solo argumento de objeto “props” (que proviene de propiedades) con datos y devuelve un elemento de React. Llamamos a dichos componentes “funcionales” porque literalmente son funciones JavaScript.
También puedes utilizar una clase de ES6 para definir un componente:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Los dos componentes anteriores son equivalentes desde el punto de vista de React.
Tanto los componentes de función como de clase tienen algunas características adicionales que veremos en las próximas secciones.
Renderizando un componente
Anteriormente, sólo encontramos elementos de React que representan las etiquetas del DOM:
const element = <div />;
Sin embargo, los elementos también pueden representar componentes definidos por el usuario:
const element = <Welcome name="Sara" />;
Cuando React ve un elemento representando un componente definido por el usuario, pasa atributos JSX e hijos a este componente como un solo objeto. Llamamos a este objeto “props”.
Por ejemplo, este código muestra “Hello, Sara” en la página:
function Welcome(props) { return <h1>Hello, {props.name}</h1>;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
const element = <Welcome name="Sara" />;root.render(element);
Recapitulemos lo que sucede en este ejemplo:
- Llamamos a
root.render()
con el elemento<Welcome name="Sara" />
. - React llama al componente
Welcome
con{name: 'Sara'}
como “props”. - Nuestro componente
Welcome
devuelve un elemento<h1>Hello, Sara</h1>
como resultado. - React DOM actualiza eficientemente el DOM para que coincida con
<h1>Hello, Sara</h1>
.
Nota: Comienza siempre los nombres de componentes con una letra mayúscula.
React trata los componentes que empiezan con letras minúsculas como etiquetas del DOM. Por ejemplo,
<div />
representa una etiqueta div HTML pero<Welcome />
representa un componente y requiere queWelcome
esté definido.Para saber más sobre el razonamiento detrás de esta convención, puedes consultar JSX en profundidad.
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>
);
}
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>
);
}
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} /> );
}
El Avatar
no necesita saber que está siendo renderizado dentro de un Comment
. Esto es por lo que le dimos a su propiedad un nombre más genérico: user
en vez de author
.
Recomendamos nombrar las props desde el punto de vista del componente, en vez de la del contexto en el que se va a utilizar.
Ahora podemos simplificar Comment
un poquito:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} /> <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>
);
}
A continuación, vamos a extraer un componente UserInfo
que renderiza un Avatar
al lado del nombre del usuario:
function UserInfo(props) {
return (
<div className="UserInfo"> <Avatar user={props.user} /> <div className="UserInfo-name"> {props.user.name} </div> </div> );
}
Esto nos permite simplificar Comment
aún más:
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} /> <div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
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 extraerse en un componente independiente.
Las props son de solo lectura
Ya sea que declares un componente como una función o como una clase, este nunca debe modificar sus props. Considera esta función sum
:
function sum(a, b) {
return a + b;
}
Tales funciones son llamadas “puras” porque no tratan de cambiar sus entradas, y siempre devuelven el mismo resultado para las mismas entradas.
En contraste, esta función es impura porque cambia su propia entrada:
function withdraw(account, amount) {
account.total -= amount;
}
React es bastante flexible pero tiene una sola regla estricta:
Todos los componentes de React deben actuar como funciones puras con respecto a sus props.
Por supuesto, las interfaces de usuario de las aplicaciones son dinámicas y cambian con el tiempo. En la siguiente sección, introduciremos un nuevo concepto de “estado”. El estado le permite a los componentes de React cambiar su salida a lo largo del tiempo en respuesta a acciones del usuario, respuestas de red y cualquier otra cosa, sin violar esta regla.