7 - Componentes: propiedades

El elemento fundamental que tenemos para comunicarnos con una componente son las propiedades. Mediante las propiedades podemos enviar datos a la componente para que los muestre.

En el concepto anterior vimos como pasar un valor entero a la componente Dado mediante la sintaxis (empleando una variable de estado con el API de Hook de React):

<Dado valor={valor1} />

Luego dentro de la componente 'Dado' accedemos al valor pasado mediante el parametro'props':

function Dado(props) {
    return (
        <div className="dado-recuadro">{props.valor}</div>
    );
}

Podemos pasar cualquier tipo de datos a una componente, no solo tipos primitivos como enteros, reales, string.

Problema

Confeccionar una aplicación que permita ingresar por teclado dos enteros y nos muestre la suma. Agregar a una lista todas las operaciones ejecutadas hasta este momento.

Crear un nuevo proyecto con la herramienta create-react-app llamado proyecto007

Primero creamos el archivo 'ListadoResultados.js' en la carpeta 'src' donde definimos la componente con el mismo nombre:

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;

El parámetro 'props' dispone de una propiedad llamada 'resultados' que llegará desde la componente 'App'. La misma es un vector con componentes de tipo objeto que almacenan los dos valores y el resultado de su suma.

Podemos imaginar que llega algo similar a esto:

[
  {
    valor1: 10,
    valor2: 12,
    resultado: 22
  },
  {
    valor1: 5,
    valor2: 20,
    resultado: 25
  },
  {
    valor1: 1,
    valor2: 1,
    resultado: 2
  }
]

La componente App es:

import ListadoResultados from "./ListadoResultados";
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>
      <form onSubmit={sumar}>
        <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>
      <ListadoResultados resultados={operaciones} />
    </div>
  );
}

export default App;

Importamos el archivo que contiene la componente funcional ListadoResultados:

import ListadoResultados from "./ListadoResultados";

En la función App definimos la variable de estado donde almacenaremos un arreglo con las distintas operaciones efectuadas:

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

El el bloque JSX además del formulario de entrada de datos propiamente dicho definimos un elemento de tipo 'ListadoResultados' y le pasamos la propiedad 'resultado' con el valor almacenado en la variable de estado 'operaciones':

  return (
    <div>
      <form onSubmit={sumar}>
        <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>
      <ListadoResultados resultados={operaciones} />
    </div>
  );

Cada vez que se presiona el botón sumar se ejecuta la función 'sumar' donde agregamos al estado un nuevo elemento al principio del vector, esto hará que se actualice la lista de resultados en la página sin tener que recargarla:

  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 = ''
  }

Para actualizar el estado en la variable 'operaciones' de manera correcta, necesitamos pasar otro arreglo completo. Utilizamos el operador spread para descomponer el vector actual y agregar como primer elemento la nueva operación:

    setOperacion([nuevo, ...operaciones])

Si queremos agregar la operación al final del vector luego podemos implementar la siguiente sintaxis:

    setOperacion([...operaciones, nuevo])
componentes en React