Propiedades de los componentes
Hasta el momento hemos visto como crear componentes y como utilizarlos en nuestra aplicación. Sin embargo, los componentes que hemos creados son elementos estáticos, es decir, no podemos modificar su contenido una vez que se han creado.
Para poder modificar el contenido de un componente, React nos permite utilizar las propiedades o props (abreviatura de properties). Las props son un conjunto de datos que se le pasan a un componente para que este pueda renderizarlos.
Si se trata de un componente funcional, las propiedades se reciben como parámetro de la función mediante un objeto. Cada propiedad del objeto es un atributo que se le pasa al componente. Por ejemplo, para nuestro componente Task
podríamos pasarle el nombre de la tarea y la descripción de la tarea mediante los atributos name
y description
respectivamente.
1function Task({name, description}) {2 return (3 <div>4 <h2>{name}</h2>5 <p>{description}</p>6 </div>7 );8}
Otra manera de realizar esta tarea, la cual es ampliamente utilizada, es recibiendo el objeto props
como parámetro de la función y luego acceder a las propiedades que necesitemos.
1function Task(props) {2 return (3 <div>4 <h2>{props.name}</h2>5 <p>{props.description}</p>6 </div>7 );8}
Ambas maneras son válidas, pero recomendamos utilizar la primera ya que es más clara y permite desestructurar el objeto props
para acceder a las propiedades que necesitemos.
Si se trata de un componente de clase, las propiedades se reciben como parámetro del constructor de la clase. Por ejemplo, para nuestro componente Task
podríamos pasarle una propiedad name
que contenga el nombre de la tarea y otra propiedad description
que contenga la descripción de la tarea.
1class Task extends React.Component {2 constructor(props) {3 super(props);4 }5
6 render() {7 return (8 <div>9 <h2>{this.props.name}</h2>10 <p>{this.props.description}</p>11 </div>12 );13 }14}
Por supuesto, también podemos utilizar la desestructuración del objeto props
para acceder a las propiedades que necesitemos.
1class Task extends React.Component {2 constructor({name, description}) {3 super({name, description});4 }5
6 render() {7 const {name, description} = this.props;8
9 return (10 <div>11 <h2>{name}</h2>12 <p>{description}</p>13 </div>14 );15 }16}
En cualquiera de los dos casos, para utilizar el componente Task
debemos emplear los atributos name
y description
como si se tratase de atributos de HTML.
1<Task name="Tarea 1" description="Descripción de la tarea 1" />
Al utilizar el componente Task
de esta manera, React se encarga de crear un objeto props
con las propiedades que le pasamos y se lo pasa al componente. Por lo tanto, el componente Task
recibe un objeto props
con los atributos name
y description
.
Así, podemos redefinir el componente TaskList
que vimos en el tema anterior para que utilice el componente Task
y le pase las propiedades name
y description
a cada tarea.
1function TaskList() {2 return (3 <div>4 <h1>Lista de tareas</h1>5 <Task name="Tarea 1" description="Descripción de la tarea 1" />6 <Task name="Tarea 2" description="Descripción de la tarea 2" />7 <Task name="Tarea 3" description="Descripción de la tarea 3" />8 </div>9 );10}
De manera similar, podemos redefinir el componente TaskList
empleando propiedades para pasarle el nombre de la lista de tareas y un arreglo de tareas.
1function TaskList({ name, tasks }) {2 return (3 <div>4 <h1>{name}</h1>5 {tasks.map((task) => (6 <Task name={task.name} description={task.description} />7 ))}8 </div>9 );10}
Ahora, el componente TaskList
puede renderizar una cantidad arbitraria de elementos Task
a partir de un arreglo de tareas (para lo cual utilizamos el método map
) y un nombre para la lista de tareas (que se renderiza como un encabezado h1
).
Con este cambio, podemos utilizar el componente TaskList
dentro del componente App
para renderizar una lista de tareas.
1function App() {2 const tasks = [3 { name: "Aprender HTML", description: "Aprender HTML es muy fácil" },4 { name: "Aprender CSS", description: "Aprender CSS puede ser un poco tedioso" },5 { name: "Aprender JavaScript", description: "Aprender JavaScript es muy divertido" },6 { name: "Aprender React", description: "Aprender React es muy interesante, pero puede ser un poco complicado" }7 ];8
9 return (10 <div>11 <TaskList name="Lista de tareas" tasks={tasks} />12 </div>13 );14}15
16export default App;
En resumen, las propiedades nos permiten pasar información a los componentes por medio de sus atributos. De esta manera, podemos crear componentes dinámicos que rendericen información diferente cada vez que se utilizan.
Una aplicación React desarrollada apropiadamente empleará siempre propiedades para garantizar la reutilización de componentes y la dinamicidad de la aplicación.
Propiedades por defecto
En ocasiones, es posible que no queramos indicar una propiedad al utilizar un componente o, por alguna razón, no podamos hacerlo. En estos casos, podemos definir un valor por defecto para la propiedad en cuestión y evitar un error en la renderización del componente.
Para definir un valor por defecto para una propiedad de un componente, debemos indicar un operador de asignación (=
) seguido del valor por defecto que queremos asignarle a la propiedad. Por ejemplo, para el componente Task
podríamos definir un valor por defecto para la propiedad description
de la siguiente manera.
1function Task({name, description = "Sin descripción"}) {2 return (3 <div>4 <h2>{name}</h2>5 <p>{description}</p>6 </div>7 );8}
De esta manera, si no indicamos la propiedad description
al utilizar el componente Task
, React utilizará el valor por defecto que definimos en la función.
1<Task name="Tarea 1" />
En este caso, el componente Task
se renderizará de la siguiente manera.
1<div>2 <h2>Tarea 1</h2>3 <p>Sin descripción</p>4</div>