11.2-pasando del hijo al padre

 

Tutorial: Paso de Datos entre Componentes en React

馃摎 Conceptos B谩sicos

En React, los datos fluyen de dos formas:

  1. Del Padre al Hijo: Usando props (propiedades)

  2. Del Hijo al Padre: Usando funciones callback

馃幆 Parte 1: Del Padre al Hijo (Props)

Ejemplo B谩sico

jsx

// COMPONENTE PADRE

function Padre() {

  const mensaje = "¡Hola desde el padre!";

  

  return (

    <div>

      <h2>Componente Padre</h2>

      {/* Paso de datos al hijo mediante props */}

      <Hijo mensaje={mensaje} />

    </div>

  );

}


// COMPONENTE HIJO

function Hijo(props) {

  return (

    <div style={{ backgroundColor: '#f0f0f0', padding: '20px' }}>

      <h3>Componente Hijo</h3>

      {/* Accedemos al prop recibido */}

      <p>Mensaje recibido: <strong>{props.mensaje}</strong></p>

    </div>

  );

}

Ejemplo con M煤ltiples Props

jsx

function App() {

  const usuario = {

    nombre: "Ana",

    edad: 25,

    ciudad: "Madrid"

  };


  return (

    <div>

      <h1>Aplicaci贸n Principal</h1>

      {/* Pasamos m煤ltiples props */}

      <TarjetaUsuario 

        nombre={usuario.nombre}

        edad={usuario.edad}

        ciudad={usuario.ciudad}

        esActivo={true}

      />

    </div>

  );

}


function TarjetaUsuario({ nombre, edad, ciudad, esActivo }) {

  // Desestructuraci贸n de props

  return (

    <div style={{

      border: '2px solid #4CAF50',

      borderRadius: '10px',

      padding: '20px',

      margin: '20px',

      backgroundColor: esActivo ? '#e8f5e9' : '#f5f5f5'

    }}>

      <h3>Usuario: {nombre}</h3>

      <p>Edad: {edad} a帽os</p>

      <p>Ciudad: {ciudad}</p>

      <p>Estado: {esActivo ? '✅ Activo' : '❌ Inactivo'}</p>

    </div>

  );

}

馃攧 Parte 2: Del Hijo al Padre (Funciones Callback)

⚡ EL CONCEPTO CLAVE

El padre le pasa al hijo una funci贸n, y el hijo la ejecuta con datos

jsx

// COMPONENTE PADRE

function Padre() {

  const [mensajeRecibido, setMensajeRecibido] = useState("");


  // ⭐ Funci贸n que recibe datos del hijo

  const recibirDatosDelHijo = (datos) => {

    setMensajeRecibido(datos);

    console.log("Padre recibi贸:", datos);

  };


  return (

    <div style={{ backgroundColor: '#e3f2fd', padding: '20px' }}>

      <h2>馃彔 Componente Padre</h2>

      <p>Mensaje del hijo: <strong>{mensajeRecibido}</strong></p>

      

      {/* Paso la funci贸n al hijo como prop */}

      <Hijo enviarAlPadre={recibirDatosDelHijo} />

    </div>

  );

}


// COMPONENTE HIJO

function Hijo({ enviarAlPadre }) {

  const [inputValue, setInputValue] = useState("");


  const manejarEnvio = () => {

    if (inputValue.trim()) {

      // ⭐ Ejecuto la funci贸n del padre con mis datos

      enviarAlPadre(inputValue);

      setInputValue("");

    }

  };


  return (

    <div style={{ backgroundColor: '#f3e5f5', padding: '20px', marginTop: '20px' }}>

      <h3>馃懚 Componente Hijo</h3>

      <input

        type="text"

        value={inputValue}

        onChange={(e) => setInputValue(e.target.value)}

        placeholder="Escribe un mensaje para el padre"

        style={{ padding: '10px', width: '300px' }}

      />

      <button 

        onClick={manejarEnvio}

        style={{ padding: '10px 20px', marginLeft: '10px' }}

      >

        Enviar al Padre 馃摛

      </button>

    </div>

  );

}

馃幃 Ejemplo Interactivo: Contador Padre-Hijo

jsx

function ContadorApp() {

  const [contadorPadre, setContadorPadre] = useState(0);


  // Funci贸n que recibe datos del hijo

  const actualizarContador = (nuevoValor) => {

    setContadorPadre(nuevoValor);

  };


  return (

    <div style={{ textAlign: 'center', padding: '40px' }}>

      <h1>馃敘 CONTADOR PADRE-HIJO</h1>

      

      <div style={{ 

        backgroundColor: '#bbdefb', 

        padding: '30px', 

        borderRadius: '10px',

        marginBottom: '30px'

      }}>

        <h2>Padre</h2>

        <p style={{ fontSize: '48px', fontWeight: 'bold' }}>

          {contadorPadre}

        </p>

      </div>


      {/* Paso la funci贸n al hijo */}

      <Botonera 

        enviarContador={actualizarContador}

        contadorActual={contadorPadre}

      />

    </div>

  );

}


function Botonera({ enviarContador, contadorActual }) {

  const incrementar = () => {

    // Env铆o el nuevo valor al padre

    enviarContador(contadorActual + 1);

  };


  const decrementar = () => {

    enviarContador(contadorActual - 1);

  };


  const reiniciar = () => {

    enviarContador(0);

  };


  return (

    <div style={{ 

      backgroundColor: '#fce4ec', 

      padding: '30px', 

      borderRadius: '10px'

    }}>

      <h3>Hijo: Botonera de Control</h3>

      

      <div style={{ marginTop: '20px' }}>

        <button 

          onClick={incrementar}

          style={styles.boton}

        >

          ➕ Incrementar

        </button>

        

        <button 

          onClick={decrementar}

          style={styles.boton}

        >

          ➖ Decrementar

        </button>

        

        <button 

          onClick={reiniciar}

          style={{...styles.boton, backgroundColor: '#f44336'}}

        >

          馃攧 Reiniciar

        </button>

      </div>

      

      <p style={{ marginTop: '20px' }}>

        <small>El hijo controla el contador del padre</small>

      </p>

    </div>

  );

}


const styles = {

  boton: {

    padding: '15px 25px',

    margin: '0 10px',

    fontSize: '16px',

    backgroundColor: '#4CAF50',

    color: 'white',

    border: 'none',

    borderRadius: '5px',

    cursor: 'pointer'

  }

};

馃摑 Ejemplo Pr谩ctico: Formulario de Tareas

jsx

function AppTareas() {

  const [tareas, setTareas] = useState([]);


  // Funci贸n para agregar tarea desde el hijo

  const agregarTarea = (nuevaTarea) => {

    setTareas([...tareas, {

      id: Date.now(),

      texto: nuevaTarea,

      completada: false

    }]);

  };


  return (

    <div style={{ maxWidth: '600px', margin: '0 auto', padding: '20px' }}>

      <h1>馃搵 Lista de Tareas</h1>

      

      {/* Paso la funci贸n al formulario hijo */}

      <FormularioTarea onAgregarTarea={agregarTarea} />

      

      {/* Lista de tareas */}

      <div style={{ marginTop: '30px' }}>

        <h3>Tareas ({tareas.length})</h3>

        {tareas.map(tarea => (

          <div key={tarea.id} style={styles.tarea}>

            {tarea.texto}

          </div>

        ))}

      </div>

    </div>

  );

}


function FormularioTarea({ onAgregarTarea }) {

  const [input, setInput] = useState("");


  const manejarSubmit = (e) => {

    e.preventDefault();

    if (input.trim()) {

      // ⭐ Llamo a la funci贸n del padre con mi dato

      onAgregarTarea(input);

      setInput("");

    }

  };


  return (

    <form onSubmit={manejarSubmit} style={styles.form}>

      <input

        type="text"

        value={input}

        onChange={(e) => setInput(e.target.value)}

        placeholder="Nueva tarea..."

        style={styles.input}

      />

      <button type="submit" style={styles.botonAgregar}>

        Agregar Tarea

      </button>

    </form>

  );

}


const styles = {

  form: {

    display: 'flex',

    gap: '10px',

    marginBottom: '20px'

  },

  input: {

    flex: 1,

    padding: '12px',

    fontSize: '16px',

    border: '2px solid #ddd',

    borderRadius: '4px'

  },

  botonAgregar: {

    padding: '12px 24px',

    backgroundColor: '#2196F3',

    color: 'white',

    border: 'none',

    borderRadius: '4px',

    cursor: 'pointer',

    fontSize: '16px'

  },

  tarea: {

    backgroundColor: '#f5f5f5',

    padding: '15px',

    marginBottom: '10px',

    borderRadius: '4px',

    borderLeft: '4px solid #4CAF50'

  }

};

馃帗 Explicaci贸n Visual del Flujo

Del Padre al Hijo

text

PADRE ──[props]──> HIJO

    (datos: string, number, array, object)

Del Hijo al Padre

text

PADRE ──[funci贸n]──> HIJO

    ⬆

HIJO ──[datos]──> PADRE

    (ejecuta la funci贸n con datos)

馃搶 Reglas de Oro

1. Los Props Son de Solo Lectura

jsx

// ❌ NO HAGAS ESTO

function Hijo(props) {

  props.mensaje = "Cambiado"; // ERROR

  return <div>{props.mensaje}</div>;

}


// ✅ HAZ ESTO

function Hijo({ mensaje }) {

  return <div>{mensaje}</div>; // Solo lectura

}

2. Tipos de Datos que se Pueden Pasar

jsx

<PasoDeDatos

  texto="Hola"              // String

  numero={42}              // Number

  booleano={true}          // Boolean

  arreglo={[1, 2, 3]}      // Array

  objeto={{nombre: "Ana"}} // Object

  funcion={() => {}}       // Function

  elemento={<div>Hola</div>} // JSX

  componente={<MiComponente />} // Componente

/>

3. Patr贸n Com煤n: Lift State Up

jsx

// El estado vive en el componente m谩s alto que lo necesita

function Abuelo() {

  const [estado, setEstado] = useState(""); // Estado aqu铆

  

  return (

    <Padre 

      estado={estado} 

      setEstado={setEstado} 

    />

  );

}


function Padre({ estado, setEstado }) {

  return <Hijo estado={estado} setEstado={setEstado} />;

}


function Hijo({ estado, setEstado }) {

  // Todos pueden leer y actualizar el estado

  return <button onClick={() => setEstado("Nuevo")}>Cambiar</button>;

}

馃殌 Ejemplo Final: Chat Padre-Hijo

jsx

function ChatApp() {

  const [mensajes, setMensajes] = useState([

    { id: 1, texto: "Hola hijo!", de: "padre" },

    { id: 2, texto: "Hola padre!", de: "hijo" }

  ]);


  const agregarMensaje = (texto, autor) => {

    setMensajes([...mensajes, {

      id: Date.now(),

      texto,

      de: autor

    }]);

  };


  return (

    <div style={styles.chatContainer}>

      <h1>馃挰 Chat Padre-Hijo</h1>

      

      <div style={styles.mensajes}>

        {mensajes.map(msg => (

          <div 

            key={msg.id} 

            style={{

              ...styles.mensaje,

              alignSelf: msg.de === 'padre' ? 'flex-start' : 'flex-end',

              backgroundColor: msg.de === 'padre' ? '#e3f2fd' : '#fce4ec'

            }}

          >

            {msg.texto}

          </div>

        ))}

      </div>


      <div style={styles.controles}>

        <PadreChat onEnviar={texto => agregarMensaje(texto, 'padre')} />

        <HijoChat onEnviar={texto => agregarMensaje(texto, 'hijo')} />

      </div>

    </div>

  );

}


function PadreChat({ onEnviar }) {

  const [input, setInput] = useState("");

  

  return (

    <div style={styles.chatBox}>

      <h3>馃懆 Padre</h3>

      <input

        value={input}

        onChange={e => setInput(e.target.value)}

        placeholder="Escribe al hijo..."

      />

      <button onClick={() => { onEnviar(input); setInput(""); }}>

        Enviar al Hijo

      </button>

    </div>

  );

}


function HijoChat({ onEnviar }) {

  const [input, setInput] = useState("");

  

  return (

    <div style={styles.chatBox}>

      <h3>馃懄 Hijo</h3>

      <input

        value={input}

        onChange={e => setInput(e.target.value)}

        placeholder="Escribe al padre..."

      />

      <button onClick={() => { onEnviar(input); setInput(""); }}>

        Enviar al Padre

      </button>

    </div>

  );

}


const styles = {

  chatContainer: {

    maxWidth: '800px',

    margin: '0 auto',

    padding: '20px'

  },

  mensajes: {

    display: 'flex',

    flexDirection: 'column',

    gap: '10px',

    height: '300px',

    overflowY: 'auto',

    padding: '20px',

    backgroundColor: '#f5f5f5',

    borderRadius: '10px',

    marginBottom: '20px'

  },

  mensaje: {

    padding: '10px 15px',

    borderRadius: '15px',

    maxWidth: '60%'

  },

  controles: {

    display: 'flex',

    gap: '20px'

  },

  chatBox: {

    flex: 1,

    padding: '20px',

    backgroundColor: '#e8f5e9',

    borderRadius: '10px'

  }

};

✅ Resumen

Direcci贸n

C贸mo se hace

Ejemplo

Padre → Hijo

Pasando props

<Hijo dato={valor} />

Hijo → Padre

Pasando funci贸n callback

<Hijo onEvento={manejar} />

Flujo Completo Hijo → Padre:

  1. Padre define una funci贸n que recibe datos

  2. Padre pasa esa funci贸n al hijo como prop

  3. Hijo ejecuta esa funci贸n con sus datos

  4. Padre recibe los datos y actualiza su estado

¡Ahora puedes hacer que tus componentes se comuniquen en ambas direcciones! 


Comentarios

Entradas m谩s populares de este blog

9.3-Tutorial de Componentes React con Props -SSS

9.6-Ciclo de Vida de un Componente React

9-Componentes en React-estado