Pasar propiedades de hijo a padre en React
Pasar propiedades de hijo a padre en React
En React, el flujo de datos es unidireccional: de padre a hijo. Para pasar datos del hijo al padre, se usa una técnica llamada "lifting state up" (elevar el estado) o pasar callbacks como props.
Concepto básico
El padre pasa una función como prop al hijo, y el hijo llama a esa función con los datos que quiere enviar al padre.
Ejemplo 1: Contador simple
// Componente Padre
import React, { useState } from 'react';
import Hijo from './Hijo';
function Padre() {
const [valorDesdeHijo, setValorDesdeHijo] = useState('');
// Función que recibirá datos del hijo
const manejarDatosDelHijo = (datos) => {
setValorDesdeHijo(datos);
};
return (
<div style={{ padding: '20px', border: '2px solid blue' }}>
<h2>Componente Padre</h2>
<p>Valor recibido del hijo: <strong>{valorDesdeHijo}</strong></p>
{/* Pasamos la función como prop al hijo */}
<Hijo onEnviarDatos={manejarDatosDelHijo} />
</div>
);
}
export default Padre;// Componente Hijo
import React, { useState } from 'react';
function Hijo({ onEnviarDatos }) {
const [inputValue, setInputValue] = useState('');
const manejarCambio = (e) => {
setInputValue(e.target.value);
};
const manejarEnvio = () => {
// Llamamos a la función del padre con los datos
onEnviarDatos(inputValue);
setInputValue('');
};
return (
<div style={{ padding: '15px', border: '1px solid green', marginTop: '10px' }}>
<h3>Componente Hijo</h3>
<input
type="text"
value={inputValue}
onChange={manejarCambio}
placeholder="Escribe algo..."
/>
<button onClick={manejarEnvio}>Enviar al padre</button>
</div>
);
}
export default Hijo;Ejemplo 2: Formulario de tareas
// Componente Padre - Lista de tareas
import React, { useState } from 'react';
import FormularioTarea from './FormularioTarea';
function ListaTareas() {
const [tareas, setTareas] = useState([]);
// Función para agregar nueva tarea desde el hijo
const agregarTarea = (nuevaTarea) => {
setTareas([...tareas, {
id: Date.now(),
texto: nuevaTarea,
completada: false
}]);
};
return (
<div style={{ padding: '20px', maxWidth: '500px' }}>
<h1>Lista de Tareas</h1>
{/* Pasamos la función para agregar tareas */}
<FormularioTarea onAgregarTarea={agregarTarea} />
<h3>Tareas:</h3>
<ul>
{tareas.map(tarea => (
<li key={tarea.id}>
{tarea.texto}
{tarea.completada && ' ✓'}
</li>
))}
</ul>
</div>
);
}
export default ListaTareas;// Componente Hijo - Formulario de tarea
import React, { useState } from 'react';
function FormularioTarea({ onAgregarTarea }) {
const [textoTarea, setTextoTarea] = useState('');
const manejarSubmit = (e) => {
e.preventDefault();
if (textoTarea.trim() === '') return;
// Enviamos la nueva tarea al padre
onAgregarTarea(textoTarea);
setTextoTarea('');
};
return (
<form onSubmit={manejarSubmit} style={{ marginBottom: '20px' }}>
<input
type="text"
value={textoTarea}
onChange={(e) => setTextoTarea(e.target.value)}
placeholder="Nueva tarea..."
style={{ padding: '8px', marginRight: '10px' }}
/>
<button type="submit">Agregar Tarea</button>
</form>
);
}
export default FormularioTarea;Ejemplo 3: Componente de calificación
// Componente Padre - Aplicación de reseñas
import React, { useState } from 'react';
import SelectorCalificacion from './SelectorCalificacion';
function AppReseñas() {
const [calificacion, setCalificacion] = useState(0);
const [reseñas, setReseñas] = useState([]);
// Función para manejar la calificación del hijo
const manejarCalificacion = (valor, comentario) => {
setCalificacion(valor);
// Agregar a la lista de reseñas
setReseñas([
...reseñas,
{ valor, comentario, fecha: new Date().toLocaleDateString() }
]);
};
return (
<div style={{ padding: '20px', fontFamily: 'Arial' }}>
<h1>Sistema de Reseñas</h1>
<p>Calificación actual: {calificacion}/5</p>
{/* Pasamos la función al hijo */}
<SelectorCalificacion onCalificar={manejarCalificacion} />
<h3>Reseñas anteriores:</h3>
{reseñas.length === 0 ? (
<p>No hay reseñas aún</p>
) : (
<ul>
{reseñas.map((reseña, index) => (
<li key={index}>
<strong>{reseña.valor}/5</strong> - {reseña.comentario}
<span style={{ color: 'gray', fontSize: '0.8em', marginLeft: '10px' }}>
({reseña.fecha})
</span>
</li>
))}
</ul>
)}
</div>
);
}
export default AppReseñas;// Componente Hijo - Selector de calificación
import React, { useState } from 'react';
function SelectorCalificacion({ onCalificar }) {
const [calificacionSeleccionada, setCalificacionSeleccionada] = useState(0);
const [comentario, setComentario] = useState('');
const manejarClickEstrella = (valor) => {
setCalificacionSeleccionada(valor);
};
const manejarEnvio = () => {
if (calificacionSeleccionada === 0) {
alert('Por favor, selecciona una calificación');
return;
}
// Enviamos la calificación y comentario al padre
onCalificar(calificacionSeleccionada, comentario);
setComentario('');
};
return (
<div style={{ padding: '15px', border: '1px solid #ddd', borderRadius: '5px' }}>
<h3>Califica nuestro servicio:</h3>
<div style={{ marginBottom: '10px' }}>
{[1, 2, 3, 4, 5].map((estrella) => (
<button
key={estrella}
onClick={() => manejarClickEstrella(estrella)}
style={{
fontSize: '24px',
background: 'none',
border: 'none',
cursor: 'pointer',
color: estrella <= calificacionSeleccionada ? 'gold' : 'lightgray'
}}
>
{estrella <= calificacionSeleccionada ? '★' : '☆'}
</button>
))}
<span style={{ marginLeft: '10px' }}>{calificacionSeleccionada}/5</span>
</div>
<textarea
value={comentario}
onChange={(e) => setComentario(e.target.value)}
placeholder="Comentario opcional..."
style={{ width: '100%', padding: '8px', marginBottom: '10px' }}
/>
<button onClick={manejarEnvio} style={{ padding: '8px 16px' }}>
Enviar Calificación
</button>
</div>
);
}
export default SelectorCalificacion;Resumen de la técnica
En el componente padre: Define una función que manejará los datos recibidos del hijo.
Pasa la función como prop al componente hijo.
En el componente hijo: Recibe la función como prop y la llama cuando necesite enviar datos al padre.
El hijo pasa los datos como argumento(s) de la función.
Ventajas de este patrón
Mantiene el flujo de datos predecible
Centraliza el estado en el componente padre
Facilita la comunicación entre componentes hermanos (a través del padre común)
Hace los componentes hijos más reutilizables
Este patrón es fundamental en React y se usa constantemente en aplicaciones reales.
Comentarios
Publicar un comentario