Administrar eventos de usuario en React con TypeScript
Este tutorial mostrará cómo administrar los eventos de los usuarios en React con TypeScript al pasar una función onClick
de un componente a otro en las acciones de un usuario.
Administrar eventos de usuario en React con TypeScript
Usaremos create-react-app
para iniciar y ejecutar rápidamente un nuevo proyecto React.
npx create-react-app my-app --template typescript
cd my-app
npm run start
Tras instalar los paquetes necesarios e iniciar el servidor de desarrollo, iremos a src/App.tsx
, borraremos todo el código repetitivo y dejaremos un componente vacío.
import React from "react";
function Message() {
return <div></div>;
}
export default Message;
Ahora agregaremos un botón al div
en el que el usuario puede hacer clic, y responderemos pasando una función con una alerta dentro del accesorio onClick
.
function Message() {
return (
<div>
<button
onClick={() => {
alert("I was clicked!");
}}>
Click Me!
</button>
</div>
);
}
Nada cambia de Vanilla React a TypeScript, pero las cosas son diferentes una vez que queremos que la función onClick
se pase como accesorio del componente Message
. Para mostrar esto, crearemos otro componente llamado Game
que tendrá como hijo a Message
.
function Game() {
return (
<div>
<Message></Message>
</div>
);
}
export default Game;
Y haremos que Message
reciba su función onClick
y text
como accesorios provenientes de Game
.
function Message({onClick, text}) {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
function Game() {
return (
<div>
<Message
onClick={() => {
alert("I was clicked!");
}}
text="Click me!"></Message>
</div>
);
}
Sin embargo, obtendremos los siguientes errores de compilación si ejecutamos este código.
Binding element 'onClick' implicitly has an 'any' type.
Binding element 'text' implicitly has an 'any' type.
En Vanilla JavaScript, esto no causa un error, pero TypeScript arroja uno ya que los accesorios onClick
y text
de Message
implícitamente tienen un tipo any
, es decir, no declaramos qué tipo deberían esos accesorios. Tienda. Debemos crear una interfaz especificando que tipo deben tener los props del Message
para solucionar esto.
interface MessageProps {
text: string;
onClick: {};
}
El valor que debe tener el accesorio text
es fácil de declarar ya que es solo una cadena. Pero el valor de onClick
es más difícil.
onClick
es más que una función normal ya que tiene una propiedad event
, y es una propiedad predeterminada del elemento button
. Entonces, para definir onClick
, necesitamos una interfaz predefinida que viene con React, que en este caso se llama ButtonHTMLAttributes
y contiene todos los tipos de propiedad del elemento button
.
Para usarlo, tenemos que extender la interfaz MessageProps
para almacenar los tipos ButtonHTMLAttributes
.
interface MessageProps extends ButtonHTMLAttributes {
text: string;
}
Sin embargo, esto no es suficiente, y ejecutar el código de esta manera generará un error ya que la interfaz ButtonHTMLAttributes
es un Tipo genérico. Puede pensar en los tipos genéricos como interfaces con variables y, para usarlos, los envolvemos con <>
después de declarar la interfaz.
En este caso, la interfaz ButtonHTMLAttributes
necesita una variable para saber qué elemento HTML estamos utilizando, y será el HTMLButtonElement global.
interface MessageProps extends ButtonHTMLAttributes<HTMLButtonElement> {
text: string;
}
MessageProps
no solo contiene los tipos de accesorios text
y onClick
, sino también los tipos de todos los accesorios de un elemento button
. Puedes añadir cualquier prop de un button
a Message
.
En caso de que solo desee extender el accesorio onClick
, no extienda la interfaz, cree un nuevo tipo onClick
y asigne la propiedad onClick
de ButtonHTMLAttributes
usando Tipos de acceso indexados.
interface MessageProps {
text: string;
onClick: ButtonHTMLAttributes<HTMLButtonElement>["onClick"];
}
Para terminar, debemos declarar que el componente Message
utilizará MessageProps
para sus props de la siguiente forma.
function Message({onClick, text}: MessageProps) {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
Y si queremos, podemos anotar el tipo de devolución para que sea un JSX.Element
para que TypeScript arroje un error si accidentalmente devolvemos algún otro tipo.
function Message({onClick, text}: MessageProps): JSX.Element {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
Y este sería el resultado final.
import React from "react";
import {ButtonHTMLAttributes} from "react";
interface MessageProps {
text: string;
onClick: ButtonHTMLAttributes<HTMLButtonElement>["onClick"];
}
function Message({onClick, text}: MessageProps): JSX.Element {
return (
<div>
<button onClick={onClick}>{text}</button>
</div>
);
}
function Game() {
return (
<div>
<Message
onClick={() => {
alert("I was clicked!");
}}
text="Click me!"></Message>
</div>
);
}
export default Game;
Juan Diego Rodríguez (also known as Monknow) is a front-end developer from Venezuela who loves to stay updated with the latest web development trends, making beautiful websites with modern technologies. But also enjoys old-school development and likes building layouts with vanilla HTML and CSS to relax.
LinkedIn