8 - Componentes: eventos generados por una componente

Una aplicación consta de una componente principal (utilizando la herramienta create-react-app se llama App), en esta definimos objetos de otras componentes y así sucesivamente cada componente puede estar construida en base a otras componentes.

Veremos ahora que una componente puede emitir un evento para informar a la componente padre un suceso.

Problema

Modificaremos el proyecto del concepto anterior para implementar el formulario de entrada de datos en otra componente llamada 'FormularioNumeros'. Las componentes que ahora tendrá la aplicación son:

componentes React

Debemos crear el archivo 'FormularioNumeros.js' en la carpeta 'src' con el siguiente contenido:

function FormularioNumeros(props) {
    return (
        <form onSubmit={props.onSumar}>
          <p>Ingrese primer valor:<input type="text" name="valor1" /></p>
          <p>Ingrese segundo valor:<input type="text" name="valor2" /></p>
          <input type="submit" value="Sumar" />
        </form>
        );
}

export default FormularioNumeros;

En el evento onSubmit le pasaremos la referencia a una función que llega como una propiedad en el parámetro 'props' y lo llama en la componente padre con el nombre 'onSumar:

      <FormularioNumeros onSumar={sumar} />

Ahora el código de la componente 'App' queda con la siguiente sintaxis:

import ListadoResultados from "./ListadoResultados";
import FormularioNumeros from "./FormularioNumeros";
import { useState } from "react";

function App() {

  const [operaciones, setOperacion] = useState([])

  function sumar(event) {
    event.preventDefault();
    const v1 = parseInt(event.target.valor1.value, 10)
    const v2 = parseInt(event.target.valor2.value, 10)
    const suma = v1 + v2
    const nuevo = {
      resultado: suma,
      valor1: v1,
      valor2: v2
    }
    setOperacion([nuevo, ...operaciones])
    event.target.valor1.value = ''
    event.target.valor2.value = ''
  }

  return (
    <div>
      <FormularioNumeros onSumar={sumar} />
      <ListadoResultados resultados={operaciones} />
    </div>
  );
}

export default App;

Debemos importar primero los dos archivos que contienen las componentes:

import ListadoResultados from "./ListadoResultados";
import FormularioNumeros from "./FormularioNumeros";

El bloque JSX ahora queda muy simple, hemos inicializado la propiedad 'onSumar' con la referencia de la función 'sumar':

  return (
    <div>
      <FormularioNumeros onSumar={sumar} />
      <ListadoResultados resultados={operaciones} />
    </div>
  );

Como vemos la función 'sumar' se ejecuta cuando la componente FormularioNumeros lo requiera.

Finalmente el archivo 'ListadoResultados' no varía con respecto al problema anterior:

function ListadoResultados(props) {
  return (
    <ul>
      {props.resultados.map((elemento) => 
        <li>La suma de {elemento.valor1} y {elemento.valor2} es {elemento.resultado}</li>
      )}
    </ul>
  );
}

export default ListadoResultados;