En aquest tema, aprendrem com integrar TypeScript amb React per crear aplicacions robustes i mantenibles. React és una biblioteca de JavaScript per construir interfícies d'usuari, i TypeScript ens ajuda a escriure codi més segur i previsible. Combinats, ens permeten desenvolupar aplicacions amb una millor experiència de desenvolupament i menys errors en temps d'execució.

Continguts

Configuració del Projecte

Creació del Projecte amb Create React App

El mètode més senzill per començar un projecte de React amb TypeScript és utilitzar Create React App. Executa la següent comanda per crear un nou projecte:

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

Això crearà una nova aplicació de React amb TypeScript ja configurat.

Configuració Manual

Si prefereixes configurar el projecte manualment, segueix aquests passos:

  1. Inicialitza un nou projecte de React:

    npx create-react-app my-app
    cd my-app
    
  2. Instal·la les dependències de TypeScript:

    npm install --save typescript @types/node @types/react @types/react-dom @types/jest
    
  3. Crea un fitxer tsconfig.json:

    {
      "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"]
    }
    
  4. Renombra els fitxers .js a .tsx:

    Renombra els fitxers de component de React de .js a .tsx per indicar que contenen JSX i TypeScript.

Components amb TypeScript

Components Funcionals

Els components funcionals són la manera més comuna de crear components en React. Aquí tens un exemple d'un component funcional amb TypeScript:

import React from 'react';

interface GreetingProps {
  name: string;
}

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

export default Greeting;

Components de Classe

Encara que els components funcionals són més comuns, també pots utilitzar components de classe amb TypeScript:

import React, { Component } from 'react';

interface GreetingProps {
  name: string;
}

class Greeting extends Component<GreetingProps> {
  render() {
    return <h1>Hello, {this.props.name}!</h1>;
  }
}

export default Greeting;

Propietats i Estats

Propietats (Props)

Les propietats es defineixen utilitzant interfícies. Aquí tens un exemple:

interface ButtonProps {
  label: string;
  onClick: () => void;
}

const Button: React.FC<ButtonProps> = ({ label, onClick }) => {
  return <button onClick={onClick}>{label}</button>;
};

Estats (State)

Per gestionar l'estat en components de classe, utilitza el tipus State:

interface CounterState {
  count: number;
}

class Counter extends Component<{}, CounterState> {
  state: CounterState = {
    count: 0
  };

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

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

Refs i Context

Refs

Els refs es poden utilitzar per accedir directament a un element DOM o a un component fill:

import React, { useRef } from 'react';

const InputFocus: React.FC = () => {
  const inputRef = useRef<HTMLInputElement>(null);

  const focusInput = () => {
    inputRef.current?.focus();
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
};

Context

El context permet passar dades a través de l'arbre de components sense haver de passar explícitament les propietats a cada nivell:

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

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

const ThemeContext = createContext<ThemeContextProps | undefined>(undefined);

const ThemeProvider: React.FC = ({ children }) => {
  const [theme, setTheme] = React.useState('light');

  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

const ThemedComponent: React.FC = () => {
  const context = useContext(ThemeContext);

  if (!context) {
    throw new Error('ThemedComponent must be used within a ThemeProvider');
  }

  return (
    <div style={{ background: context.theme === 'light' ? '#fff' : '#333', color: context.theme === 'light' ? '#000' : '#fff' }}>
      <p>The current theme is {context.theme}</p>
      <button onClick={context.toggleTheme}>Toggle Theme</button>
    </div>
  );
};

export { ThemeProvider, ThemedComponent };

Hooks amb TypeScript

useState

El hook useState es pot utilitzar amb TypeScript de la següent manera:

import React, { useState } from 'react';

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

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

useEffect

El hook useEffect es pot utilitzar per gestionar efectes secundaris:

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

const DataFetcher: React.FC = () => {
  const [data, setData] = useState<string | null>(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return <div>{data ? data : 'Loading...'}</div>;
};

Exercicis Pràctics

Exercici 1: Crear un Component de Llista

Crea un component que mostri una llista d'elements. Cada element ha de tenir un nom i una descripció.

Solució

import React from 'react';

interface ListItem {
  name: string;
  description: string;
}

interface ListProps {
  items: ListItem[];
}

const List: React.FC<ListProps> = ({ items }) => {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>
          <h3>{item.name}</h3>
          <p>{item.description}</p>
        </li>
      ))}
    </ul>
  );
};

export default List;

Exercici 2: Crear un Formulari amb Validació

Crea un formulari que permeti als usuaris introduir el seu nom i correu electrònic. Afegeix validació per assegurar-te que els camps no estiguin buits.

Solució

import React, { useState } from 'react';

interface FormState {
  name: string;
  email: string;
}

const Form: React.FC = () => {
  const [formState, setFormState] = useState<FormState>({ name: '', email: '' });
  const [errors, setErrors] = useState<{ name?: string; email?: string }>({});

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormState({ ...formState, [name]: value });
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const newErrors: { name?: string; email?: string } = {};

    if (!formState.name) {
      newErrors.name = 'Name is required';
    }

    if (!formState.email) {
      newErrors.email = 'Email is required';
    }

    setErrors(newErrors);

    if (Object.keys(newErrors).length === 0) {
      console.log('Form submitted successfully', formState);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>
          Name:
          <input type="text" name="name" value={formState.name} onChange={handleChange} />
        </label>
        {errors.name && <p>{errors.name}</p>}
      </div>
      <div>
        <label>
          Email:
          <input type="email" name="email" value={formState.email} onChange={handleChange} />
        </label>
        {errors.email && <p>{errors.email}</p>}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};

export default Form;

Conclusió

En aquest tema, hem après com integrar TypeScript amb React per crear aplicacions més robustes i mantenibles. Hem vist com configurar un projecte, crear components, gestionar propietats i estats, utilitzar refs i context, i treballar amb hooks. També hem practicat amb exercicis per reforçar els conceptes apresos. Amb aquests coneixements, estàs preparat per desenvolupar aplicacions de React amb TypeScript de manera eficient i segura.

© Copyright 2024. Tots els drets reservats