Introducció

Evento

Los controladores de eventos son tus propias funciones que se ejecutan en respuesta a interacciones como hacer clic, hover, enfocar inputs en formularios, entre otras.

Para agregar un controlador de evento, primero defines una función y luego la pasas como una prop a la etiqueta JSX apropiada.

Por ejemplo, este es un botón que no hace nada todavía:

export default function App() {
  return (
    <div className="m-5">
      <Button />
    </div>)
}

function Button() {
  return (
    <button className="btn btn-primary">
      No hago nada
    </button>
  )
}

Puedes hacer que muestre un mensaje cuando un usuario haga clic siguiendo estos tres pasos:

  1. Declara una función llamada handleClick dentro de tu componente Button.
  2. Implementa la lógica dentro de esa función (utiliza alert para mostrar el mensaje).
  3. Agrega onClick={handleClick} al JSX del <button>.
function Button() {

  function handleClick() {
    alert("Has fet clic")
  }

  return (
    <button className="btn btn-primary" onClick={handleClick}>
      Fes clic
    </button>
  )
}

Definiste la función handleClick y luego la pasaste como una prop al <button>.

handleClick es un controlador de evento.

Las funciones controladoras de evento:

  1. Usualmente están definidas dentro de tus componentes.
  2. Tienen nombres que empiezan con handle, seguido del nombre del evento.

Por convención, es común llamar a los controladores de eventos como handle seguido del nombre del evento.

A menudo verás onClick={handleClick}, onMouseEnter={handleMouseEnter}, etcétera.

Por otro lado, puedes definir un controlador de evento en línea en el JSX:

function Button() {

  return (
    <button className="btn btn-primary" onClick={() => {
      alert("Has fet clic")
    }}>
      Fes clic
    </button>
  )
}

⚠ Atenció!

Las funciones que se pasan a los controladores de eventos deben ser pasadas, no llamadas.

Modifica el botó, invocant la funció handleClick:

function Button() {

  function handleClick() {
    alert("Has fet clic")
  }

  return (
    <button className="btn btn-primary" onClick={handleClick()}>
      Fes clic
    </button>
  )
}

Pots veure que la funció handleClick s'executa de manera automàtica sense que l'usuari apreti el botó.

Los () al final del handleClick() ejecutan la función inmediatamente mientras se renderiza, sin ningún clic. Esto es porque el JavaScript dentro de { y } en JSX se ejecuta de inmediato.

A més, Typescript t'avisa que onClick espera una funció!

El mateix passa amb les funcions "arrow"

Això és correcte:

<button onClick={() => alert('...')}>

Això està malamanent:

<button onClick={alert('...')}>

Propietats

Como los controladores de eventos son declarados dentro de un componente, tienen acceso a las props del componente.

Este es un botón que, cuando se hace clic, muestra una alerta con su prop message:

export default function App() {
  return (
    <div className="m-5">
      <Button message="🛒 Fet!">Vull un <span className="fs-1">🦘</span></Button>
    </div>)
}

function Button({ message, children }: { message: string, children: any }) {

  return (
    <button className="btn btn-primary" onClick={() => alert(message)}>
      {children}
    </button>
  )
}

A menudo querrás que el componente padre especifique un controlador de evento de un componente hijo.

export default function App() {
  return (
    <div className="m-5">
      <Button onClick={() => alert("🛒 Fet!")}>Vull un <span className="fs-1">🦘</span></Button>
    </div>)
}

function Button({ onClick, children }: { onClick: () => void, children: any }) {

  return (
    <button className="btn btn-primary" onClick={onClick}>
      {children}
    </button>
  )
}
  1. App pasa una "arrow" function como la prop onClick al Button que está dentro.
  2. Tu componente Button acepta una prop llamada onClick, y pasa esa prop directamente al <button> integrado en el navegador con onClick={onClick}.

Continua: https://es.react.dev/learn/responding-to-events

Estat

Per conservar estat en una variable, no pots utitlizar variables locals:

  1. Las variables locales no persisten entre renderizaciones. Cuando React renderiza este componente por segunda vez, lo hace desde cero, no considera ningún cambio en las variables locales.

  2. Los cambios en las variables locales no activarán renderizaciones. React no se da cuenta de que necesita renderizar el componente nuevamente con los nuevos datos.

Para actualizar un componente con datos nuevos, deben pasar las siguientes dos cosas:

  1. Conservar los datos entre renderizaciones.
  2. Provocar que React renderice el componente con nuevos datos (re-renderizado).

El Hook de useState ofrece dos cosas:

  1. Una variable de estado para mantener los datos entre renderizados.
  2. Una función que setea el estado para actualizar la variable y provocar que React renderice el componente nuevamente.

Variable amb estat

Para agregar una variable de estado, debemos importar el useState de React al inicio del archivo:

import { useState } from 'react';

I ja pots crear una variable amb estat:

import { useState } from "react"

export default function App() {

  const [cart, setCart] = useState<string>("El 🛒 està buit!")

  return (
    <div className="m-5">
      <p className="m-5 border borde-5 p-2">{cart}</p>
      <Button onClick={() => alert("🛒 Fet!")}>Vull un <span className="fs-4">🦘</span></Button>
    </div>)
}

El único argumento para useState es el valor inicial de su variable de estado.

En este ejemplo, el valor inicial de cart se establece en "El 🛒 està buit!".

Cada vez que el componente se renderiza, el useState devuelve un array que contiene dos valores:

  1. La variable de estado (cart) con el valor que almacenaste.
  2. La función que establece el estado (setCart) que puede actualizar la variable de estado y alertar a React para que renderice el componente nuevamente.

A continuació modifica el codi perquè al apretar el butó modifique el contingut de la variable amb estat cart:

import { useState } from "react"

export default function App() {

  const [cart, setCart] = useState<string>("El 🛒 està buit!")

  return (
    <div className="m-5">
      <p className="m-5 border borde-5 p-2">{cart}</p>
      <Button onClick={() => setCart("🛒 Fet!")}>Vull un <span className="fs-4">🦘</span></Button>
    </div>)
}

Ara quan l'usuari apreti el butó, es modificarà el contingut de la variable d'estat cart, React detectarà el canvi, i tornará a renderitzar la pàgina.

Múltiples variables de estado

Podemos tener más de una variable de estado de diferentes tipos en un componente.

Este componente tiene dos variables de estado, un index numérico y un showMore booleano que se activa al hacer clic en «Mostrar detalles»:

Es una buena idea tener múltiples variables de estado si no se encuentran relacionadas entre sí, como index y showMore en este ejemplo. Pero si encontramos que a menudo cambiamos dos variables de estado juntas, podría ser mejor combinarlas en una sola. Por ejemplo, si tenemos un formulario con muchos campos, es más conveniente tener una única variable de estado que contenga un objeto que una variable de estado por campo.

CONTINUA: https://es.react.dev/learn/state-a-components-memory