Mostrando datos con Props

Hasta ahora, si reutilizas tu componente <Header />, mostraría el mismo contenido ambas veces.

index.html
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
      <Header />
    </div>
  );
}

Pero ¿qué pasa si quieres pasar texto diferente o no conoces la información de antemano porque estás obteniendo datos de una fuente externa?

Los elementos HTML normales tienen atributos que puedes usar para pasar información que cambia el comportamiento de esos elementos. Por ejemplo, cambiar el atributo src de un elemento <img> modifica la imagen que se muestra. Cambiar el atributo href de una etiqueta <a> altera el destino del enlace.

De la misma manera, puedes pasar información como propiedades a los componentes de React. Estas se llaman props. Por ejemplo, considera las posibles variaciones de un botón:

Diagrama mostrando 3 variaciones de un componente botón: Primario, Secundario y Deshabilitado

Similar a una función JavaScript, puedes diseñar componentes que acepten argumentos personalizados (o props) que cambien el comportamiento del componente o lo que se muestra visiblemente cuando se renderiza en pantalla. Luego, puedes pasar estas props desde componentes padres a componentes hijos.

Nota: En React, los datos fluyen hacia abajo en el árbol de componentes. Esto se conoce como flujo de datos unidireccional. El estado, que se discutirá en el próximo capítulo, puede pasarse de componentes padres a hijos como props.

Usando props

En tu componente HomePage, puedes pasar una prop personalizada title al componente Header, igual que pasarías atributos HTML:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
    </div>
  );
}

Y Header, el componente hijo, puede aceptar esas props como su primer parámetro de función:

index.html
function Header(props) {
  return <h1>Develop. Preview. Ship.</h1>;
}

Si usas console.log() con props, verás que es un objeto con una propiedad title.

index.html
function Header(props) {
  console.log(props); // { title: "React" }
  return <h1>Develop. Preview. Ship.</h1>;
}

Como props es un objeto, puedes usar desestructuración de objetos para nombrar explícitamente los valores de props dentro de los parámetros de tu función:

index.html
function Header({ title }) {
  console.log(title); // "React"
  return <h1>Develop. Preview. Ship.</h1>;
}

Luego puedes reemplazar el contenido de la etiqueta <h1> con tu variable title.

index.html
function Header({ title }) {
  console.log(title);
  return <h1>title</h1>;
}

Si abres tu archivo en el navegador, verás que muestra la palabra literal "title". Esto se debe a que React piensa que estás intentando renderizar una cadena de texto simple en el DOM.

Necesitas una forma de decirle a React que esto es una variable JavaScript.

Usando variables en JSX

Para usar la prop title, añade llaves . Estas son una sintaxis especial de JSX que te permite escribir JavaScript directamente dentro de tu marcado JSX.

index.html
function Header({ title }) {
  console.log(title);
  return <h1>{title}</h1>;
}

Puedes pensar en las llaves como una forma de entrar en "tierra JavaScript" mientras estás en "tierra JSX". Puedes añadir cualquier expresión JavaScript (algo que se evalúe como un único valor) dentro de llaves. Por ejemplo:

  1. Una propiedad de objeto con notación de punto:
example.js
function Header(props) {
  return <h1>{props.title}</h1>;
}
  1. Un template literal:
example.js
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
  1. El valor retornado por una función:
example.js
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}
 
function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
  1. O operadores ternarios:
example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default Title'}</h1>;
}

Ahora puedes pasar cualquier cadena a tu prop title, o, si usaste el operador ternario, incluso podrías no pasar ninguna prop title, ya que has considerado el caso por defecto en tu componente:

example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

Tu componente ahora acepta una prop title genérica que puedes reutilizar en diferentes partes de tu aplicación. Solo necesitas cambiar la cadena del título:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
      <Header title="A new title" />
    </div>
  );
}

Iterando a través de listas

Es común tener datos que necesitas mostrar como una lista. Puedes usar métodos de array para manipular tus datos y generar elementos de UI que sean idénticos en estilo pero contengan diferentes piezas de información.

Añade el siguiente array de nombres a tu componente HomePage:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

Luego puedes usar el método array.map() para iterar sobre el array y usar una función flecha para mapear un nombre a un elemento de lista:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

Observa cómo has usado llaves para alternar entre "JavaScript" y "JSX".

Si ejecutas este código, React nos dará una advertencia sobre una prop key faltante. Esto se debe a que React necesita algo que identifique únicamente los elementos en un array para saber qué elementos actualizar en el DOM.

Puedes usar los nombres por ahora ya que actualmente son únicos, pero se recomienda usar algo que garantice ser único, como un ID de elemento.

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
    </div>
  );
}

Recursos adicionales:

On this page