En este módulo, aprenderás cómo integrar TypeScript con React para crear aplicaciones robustas y con tipado estático. TypeScript puede mejorar significativamente la experiencia de desarrollo en React al proporcionar autocompletado, verificación de tipos y documentación en línea.

Contenido

Introducción a TypeScript con React

TypeScript y React son una combinación poderosa para el desarrollo de aplicaciones web. TypeScript proporciona un sistema de tipos estático que puede ayudar a prevenir errores y mejorar la mantenibilidad del código.

Ventajas de Usar TypeScript con React

  • Autocompletado y Documentación en Línea: Mejora la productividad del desarrollador.
  • Verificación de Tipos: Ayuda a detectar errores en tiempo de compilación.
  • Refactorización Segura: Facilita la modificación del código sin introducir errores.

Configuración del Proyecto

Para empezar, necesitamos configurar un proyecto de React con TypeScript. Puedes usar Create React App para configurar rápidamente un proyecto con TypeScript.

Paso 1: Crear un Proyecto con Create React App

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

Paso 2: Verificar la Configuración

Asegúrate de que los archivos tsconfig.json y package.json estén configurados correctamente. El archivo tsconfig.json debe tener configuraciones básicas para TypeScript.

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

Componentes Funcionales con TypeScript

Los componentes funcionales son una forma común de escribir componentes en React. Con TypeScript, podemos definir los tipos de las propiedades (props) que el componente acepta.

Ejemplo de Componente Funcional

import React from 'react';

interface GreetingProps {
  name: string;
}

const Greeting: React.FC<GreetingProps> = ({ name }) => {
  return <h1>Hello, {name}!</h1>;
};

export default Greeting;

Explicación

  • interface GreetingProps: Define la estructura de las propiedades que el componente acepta.
  • React.FC<GreetingProps>: Define el tipo del componente funcional, asegurando que las propiedades pasadas cumplan con la interfaz GreetingProps.

Componentes de Clase con TypeScript

Aunque los componentes funcionales son más comunes, los componentes de clase también se utilizan, especialmente cuando se necesita manejar el estado o los ciclos de vida del componente.

Ejemplo de Componente de Clase

import React, { Component } from 'react';

interface CounterProps {
  initialCount: number;
}

interface CounterState {
  count: number;
}

class Counter extends Component<CounterProps, CounterState> {
  constructor(props: CounterProps) {
    super(props);
    this.state = {
      count: props.initialCount
    };
  }

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

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

export default Counter;

Explicación

  • interface CounterProps y interface CounterState: Definen las estructuras de las propiedades y el estado del componente.
  • Component<CounterProps, CounterState>: Define el tipo del componente de clase, asegurando que las propiedades y el estado cumplan con las interfaces definidas.

Propiedades y Estado

TypeScript permite definir tipos para las propiedades (props) y el estado (state) de los componentes, lo que ayuda a prevenir errores y facilita la comprensión del código.

Ejemplo de Propiedades y Estado

import React, { useState } from 'react';

interface ToggleProps {
  initialOn: boolean;
}

const Toggle: React.FC<ToggleProps> = ({ initialOn }) => {
  const [isOn, setIsOn] = useState(initialOn);

  const toggle = () => {
    setIsOn(!isOn);
  };

  return (
    <div>
      <p>{isOn ? 'ON' : 'OFF'}</p>
      <button onClick={toggle}>Toggle</button>
    </div>
  );
};

export default Toggle;

Explicación

  • useState(initialOn): Inicializa el estado del componente con el valor de initialOn.
  • const [isOn, setIsOn]: Desestructura el estado y la función para actualizar el estado.

Hooks con TypeScript

Los hooks son una característica poderosa de React que permite usar estado y otras características de React sin escribir una clase. TypeScript puede tipar los hooks para mejorar la seguridad y la autocompletación.

Ejemplo de Hook Personalizado

import { useState } from 'react';

function useCounter(initialValue: number) {
  const [count, setCount] = useState(initialValue);

  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);

  return { count, increment, decrement };
}

export default useCounter;

Explicación

  • useCounter: Es un hook personalizado que maneja un contador.
  • initialValue: number: Define el tipo del parámetro initialValue.
  • const [count, setCount]: Desestructura el estado y la función para actualizar el estado.

Ejercicio Práctico

Ejercicio

Crea un componente de lista de tareas (ToDo List) utilizando TypeScript y React. El componente debe permitir agregar y eliminar tareas.

Requisitos

  1. Define una interfaz para las propiedades y el estado del componente.
  2. Usa un componente funcional para implementar la lista de tareas.
  3. Implementa funciones para agregar y eliminar tareas.

Solución

import React, { useState } from 'react';

interface Todo {
  id: number;
  text: string;
}

const TodoList: React.FC = () => {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [newTodo, setNewTodo] = useState('');

  const addTodo = () => {
    const newTask: Todo = { id: Date.now(), text: newTodo };
    setTodos([...todos, newTask]);
    setNewTodo('');
  };

  const removeTodo = (id: number) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  return (
    <div>
      <h1>Todo List</h1>
      <input
        type="text"
        value={newTodo}
        onChange={(e) => setNewTodo(e.target.value)}
      />
      <button onClick={addTodo}>Add</button>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            {todo.text}
            <button onClick={() => removeTodo(todo.id)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default TodoList;

Explicación

  • interface Todo: Define la estructura de una tarea.
  • useState<Todo[]>([]): Inicializa el estado de la lista de tareas como un array vacío de objetos Todo.
  • addTodo y removeTodo: Funciones para agregar y eliminar tareas de la lista.

Conclusión

En este módulo, hemos aprendido cómo integrar TypeScript con React para crear aplicaciones con tipado estático. Hemos cubierto la configuración del proyecto, la creación de componentes funcionales y de clase, el manejo de propiedades y estado, y el uso de hooks con TypeScript. Además, hemos implementado un ejercicio práctico para reforzar los conceptos aprendidos.

Próximos Pasos

En el siguiente módulo, exploraremos herramientas y mejores prácticas para trabajar con TypeScript, incluyendo linting, pruebas y configuración con Webpack.

© Copyright 2024. Todos los derechos reservados