Español

Explora las mejores prácticas para usar TypeScript con React para construir aplicaciones web robustas, escalables y mantenibles.

TypeScript con React: Mejores Prácticas para Aplicaciones Escalables y Mantenibles

TypeScript y React son una combinación poderosa para construir aplicaciones web modernas. TypeScript aporta tipado estático a JavaScript, mejorando la calidad y la mantenibilidad del código, mientras que React proporciona un enfoque declarativo y basado en componentes para construir interfaces de usuario. Esta publicación de blog explora las mejores prácticas para usar TypeScript con React para crear aplicaciones robustas, escalables y mantenibles, adecuadas para una audiencia global.

¿Por qué usar TypeScript con React?

Antes de profundizar en las mejores prácticas, entendamos por qué TypeScript es una valiosa adición al desarrollo de React:

Configuración de un proyecto React con TypeScript

Usando Create React App

La forma más fácil de iniciar un nuevo proyecto React con TypeScript es usar Create React App con la plantilla de TypeScript:

npx create-react-app my-typescript-react-app --template typescript

Este comando configura un proyecto React básico con TypeScript configurado, incluyendo las dependencias necesarias y un archivo tsconfig.json.

Configuración de tsconfig.json

El archivo tsconfig.json es el corazón de su configuración de TypeScript. Aquí hay algunas configuraciones recomendadas:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

Opciones clave a considerar:

Mejores prácticas para componentes React con TypeScript

Tipado de Props de Componentes

Uno de los aspectos más importantes de usar TypeScript con React es tipar correctamente las props de sus componentes. Use interfaces o alias de tipo para definir la forma del objeto props.

interface MyComponentProps {
  name: string;
  age?: number; // Prop opcional
  onClick: () => void;
}

const MyComponent: React.FC = ({ name, age, onClick }) => {
  return (
    

Hola, {name}!

{age &&

Tienes {age} años.

}
); };

Usar React.FC<MyComponentProps> asegura que el componente sea un componente funcional y que las props estén correctamente tipadas.

Tipado del Estado del Componente

Si está utilizando componentes de clase, también necesitará tipar el estado del componente. Defina una interfaz o un alias de tipo para el objeto de estado y úselo en la definición del componente.

interface MyComponentState {
  count: number;
}

class MyComponent extends React.Component<{}, MyComponentState> {
  state: MyComponentState = {
    count: 0
  };

  handleClick = () => {
    this.setState({
      count: this.state.count + 1
    });
  };

  render() {
    return (
      

Contador: {this.state.count}

); } }

Para componentes funcionales que usan el hook useState, TypeScript a menudo puede inferir el tipo de la variable de estado, pero también puede proporcionarlo explícitamente:

import React, { useState } from 'react';

const MyComponent: React.FC = () => {
  const [count, setCount] = useState(0);

  return (
    

Contador: {count}

); };

Usando Guardas de Tipo

Las guardas de tipo son funciones que reducen el tipo de una variable dentro de un ámbito específico. Son útiles cuando se trata de tipos de unión o cuando necesita asegurarse de que una variable tiene un tipo específico antes de realizar una operación.

interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  side: number;
}

type Shape = Circle | Square;

function isCircle(shape: Shape): shape is Circle {
  return shape.kind === "circle";
}

function getArea(shape: Shape): number {
  if (isCircle(shape)) {
    return Math.PI * shape.radius ** 2;
  } else {
    return shape.side ** 2;
  }
}

La función isCircle es una guarda de tipo que verifica si una Shape es un Circle. Dentro del bloque if, TypeScript sabe que shape es un Circle y le permite acceder a su propiedad radius.

Manejo de Eventos

Al manejar eventos en React con TypeScript, es importante tipar correctamente el objeto del evento. Use el tipo de evento apropiado del espacio de nombres React.

const MyComponent: React.FC = () => {
  const handleChange = (event: React.ChangeEvent) => {
    console.log(event.target.value);
  };

  return (
    
  );
};

En este ejemplo, React.ChangeEvent<HTMLInputElement> se usa para tipar el objeto del evento para un evento de cambio en un elemento de entrada. Esto proporciona acceso a la propiedad target, que es un HTMLInputElement.

Estructura del Proyecto

Un proyecto bien estructurado es crucial para la mantenibilidad y la escalabilidad. Aquí hay una estructura de proyecto sugerida para una aplicación React con TypeScript:

src/
├── components/
│   ├── MyComponent/
│   │   ├── MyComponent.tsx
│   │   ├── MyComponent.module.css
│   │   └── index.ts
├── pages/
│   ├── HomePage.tsx
│   └── AboutPage.tsx
├── services/
│   ├── api.ts
│   └── auth.ts
├── types/
│   ├── index.ts
│   └── models.ts
├── utils/
│   ├── helpers.ts
│   └── constants.ts
├── App.tsx
├── index.tsx
├── react-app-env.d.ts
└── tsconfig.json

Puntos clave:

Usando Hooks con TypeScript

Los Hooks de React le permiten usar el estado y otras características de React en componentes funcionales. TypeScript funciona a la perfección con Hooks, proporcionando seguridad de tipos y una mejor experiencia para el desarrollador.

useState

Como se muestra anteriormente, puede tipar explícitamente la variable de estado cuando usa useState:

import React, { useState } from 'react';

const MyComponent: React.FC = () => {
  const [count, setCount] = useState(0);

  return (
    

Contador: {count}

); };

useEffect

Cuando usa useEffect, tenga en cuenta la matriz de dependencias. TypeScript puede ayudarlo a detectar errores si olvida incluir una dependencia que se usa dentro del efecto.

import React, { useState, useEffect } from 'react';

const MyComponent: React.FC = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `Contador: ${count}`;
  }, [count]); // Agregue 'count' a la matriz de dependencias

  return (
    

Contador: {count}

); };

Si omite count de la matriz de dependencias, el efecto solo se ejecutará una vez cuando se monte el componente, y el título del documento no se actualizará cuando cambie el contador. TypeScript le advertirá sobre este posible problema.

useContext

Cuando usa useContext, necesita proporcionar un tipo para el valor del contexto.

import React, { createContext, useContext } from 'react';

interface ThemeContextType {
  theme: string;
  toggleTheme: () => void;
}

const ThemeContext = createContext(undefined);

const ThemeProvider: React.FC = ({ children }) => {
  // Implementa la lógica del tema aquí
  return (
     {} }}>
      {children}
    
  );
};

const MyComponent: React.FC = () => {
  const { theme, toggleTheme } = useContext(ThemeContext) as ThemeContextType;

  return (
    

Tema: {theme}

); }; export { ThemeProvider, MyComponent };

Al proporcionar un tipo para el valor del contexto, se asegura de que el hook useContext devuelva un valor con el tipo correcto.

Pruebas de Componentes React con TypeScript

Las pruebas son una parte esencial de la construcción de aplicaciones robustas. TypeScript mejora las pruebas al proporcionar seguridad de tipos y una mejor cobertura del código.

Pruebas Unitarias

Use marcos de prueba como Jest y React Testing Library para probar unitariamente sus componentes.

// MyComponent.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';

describe('MyComponent', () => {
  it('representa el componente con el nombre correcto', () => {
    render();
    expect(screen.getByText('Hola, John!')).toBeInTheDocument();
  });

  it('llama al manejador onClick cuando se hace clic en el botón', () => {
    const onClick = jest.fn();
    render();
    fireEvent.click(screen.getByRole('button'));
    expect(onClick).toHaveBeenCalledTimes(1);
  });
});

La comprobación de tipos de TypeScript ayuda a detectar errores en sus pruebas, como pasar props incorrectas o usar los controladores de eventos incorrectos.

Pruebas de Integración

Las pruebas de integración verifican que diferentes partes de su aplicación funcionen juntas correctamente. Use herramientas como Cypress o Playwright para las pruebas de extremo a extremo.

Optimización del Rendimiento

TypeScript también puede ayudar con la optimización del rendimiento al detectar posibles cuellos de botella de rendimiento al principio del proceso de desarrollo.

Memoización

Use React.memo para memorizar componentes funcionales y evitar renderizados innecesarios.

import React from 'react';

interface MyComponentProps {
  name: string;
}

const MyComponent: React.FC = ({ name }) => {
  console.log('Renderizando MyComponent');
  return (
    

Hola, {name}!

); }; export default React.memo(MyComponent);

React.memo solo volverá a renderizar el componente si las props han cambiado. Esto puede mejorar significativamente el rendimiento, especialmente para componentes complejos.

División de Código

Use importaciones dinámicas para dividir su código en fragmentos más pequeños y cargarlos a pedido. Esto puede reducir el tiempo de carga inicial de su aplicación.

import React, { Suspense } from 'react';

const MyComponent = React.lazy(() => import('./MyComponent'));

const App: React.FC = () => {
  return (
    Cargando...
}> ); };

React.lazy le permite importar componentes dinámicamente, que se cargan solo cuando se necesitan. El componente Suspense proporciona una interfaz de usuario de reserva mientras se carga el componente.

Conclusión

Usar TypeScript con React puede mejorar significativamente la calidad, la mantenibilidad y la escalabilidad de sus aplicaciones web. Siguiendo estas mejores prácticas, puede aprovechar el poder de TypeScript para construir aplicaciones robustas y de alto rendimiento que satisfagan las necesidades de una audiencia global. Recuerde concentrarse en definiciones de tipo claras, una organización de proyecto bien estructurada y pruebas exhaustivas para asegurar el éxito a largo plazo de sus proyectos.

Recursos Adicionales

TypeScript con React: Mejores Prácticas para Aplicaciones Escalables y Mantenibles | MLOG