TypeScript + React: практикум

TypeScript обеспечивает полную поддержку типов для разработки на React, повышая надёжность кода.

Использование TypeScript гарантирует, что компоненты React, Props, State и т. д. имеют полную проверку типов, что снижает количество ошибок во время выполнения.

Посмотреть руководство по React:https://www.example.com/vue3/react-tutorial.html


SVG-диаграмма: рабочий процесс разработки React + TypeScript Background Title React + TypeScript Type Support Components React Components React.FC<Props> interface ButtonProps { text: string React Hooks useState<T>(initial) useEffect(() => {}, []) useCallback<T>(fn) Events Event Handling React.FormEvent React.ChangeEvent React.MouseEvent Bottom half: Type Safety Advantages Brought by TypeScript Advantage 1 Compile-time Type Checking Advantage 2 Intelligent Code Completion Advantage 3 Safer Refactoring Arrow marker

Зачем нужно использовать TypeScript в React?

Компонентная разработка на React порождает большой объём потоков данных, таких как Props, State, Context и т. д.

Без определений типов сложно отследить источник и структуру данных, и могут возникать ошибки во время выполнения.

TypeScript предоставляет React полноценную систему типов: Props компонентов проверяются по типам, useState имеет вывод типов, а обработка событий — подсказки типов.

Поток данных:Поток данных в React (Props, State, Context) нуждается в определениях типов, и TypeScript может обеспечить типобезопасность потока данных.


Создание проекта

Используйте современный инструмент скаффолдинга для создания React-проекта, поддерживающего TypeScript.

Инициализация

# Используйте Create React App (медленнее, но полноценный)
npx create-react-app my-app --template typescript

# Или используйте Vite (рекомендуется, быстрее)
npm create vite@latest my-app -- --template react-ts

Рекомендация:Vite в настоящее время является наиболее рекомендуемым инструментом сборки React, с высокой скоростью и хорошим опытом разработки.


Типы компонентов

Используйте тип React.FC для определения функциональных компонентов.

src/components/Button.tsx

import React from "react";

// Определите тип Props для компонента кнопки
interface ButtonProps {
    text: string;                    // Текст кнопки (обязательно)
    onClick: () => void;             // Колбэк клика (обязательно)
    disabled?: boolean;              // Является ли disabled (необязательно, по умолчанию false)
    variant?: "primary" | "secondary"; // Вариант кнопки (необязательно)
}

// Определите тип функционального компонента с помощью React.FC
const Button: React.FC<ButtonProps> = ({
    text,
    onClick,
    disabled = false,
    variant = "primary"
}) => {
    return (
        <button
            className={`btn btn-${variant}`}
            onClick={onClick}
            disabled={disabled}
        >
            {text}
        </button>
    );
};

export default Button;

Результат выполнения:

Button 组件渲染成功

React.FC:Это тип функционального компонента React, включая встроенные типы, такие как children, propTypes и т. д.


Типы пропсов

Определите интерфейс Props компонента для передачи данных дочерним компонентам.

src/components/UserCard.tsx

import React from "react";

// Определяем тип пользователя
interface User {
    id: number;           // ID пользователя
    name: string;        // Имя пользователя
    email: string;       // Электронная почта
    avatar?: string;     // Аватар (необязательный)
}

// Определите Props для компонента карточки пользователя
interface UserCardProps {
    user: User;                       // Объект пользователя (обязательный)
    onEdit: (user: User) => void;    // Колбэк редактирования
    onDelete: (id: number) => void;  // Колбэк удаления
}

const UserCard: React.FC<UserCardProps> = ({ user, onEdit, onDelete }) => {
    return (
        <div className="user-card">
            {user.avatar && <img src={user.avatar} alt={user.name} />}
            <h3>{user.name}</h3>
            <p>{user.email}</p>
            <button onClick={() => onEdit(user)}>Редактировать</button>
            <button onClick={() => onDelete(user.id)}>Удалить</button>
        </div>
    );
};

export default UserCard;
Распространение типов:Передавайте типы через Props, чтобы обеспечить согласованность типов данных во всём дереве компонентов.

Типы useState

Укажите параметры типа для useState, чтобы обеспечить правильный тип состояния.

src/components/Counter.tsx

import React, { useState } from "react";

const Counter: React.FC = () => {
    // Базовый тип: явно указать тип number
    const [count, setCount] = useState<number>(0);

    // Тип объекта: указать тип объекта
    const [user, setUser] = useState<{ name: string; age: number }>({
        name: "Alice",
        age: 25
    });

    return (
        <div>
            <p>Количество: {count}</p>
            <button onClick={() => setCount(c => c + 1)}>+1</button>
            <button onClick={() => setCount(c => c - 1)}>-1</button>

            <p>User: {user.name}, {user.age}</p>
            <button onClick={() => setUser({ ...user, age: user.age + 1 })}>
Age+1
            </button>
        </div>
    );
};

export default Counter;

Результат выполнения:

Counter 组件渲染成功

Обобщённые параметры:T в useState<T> — это тип состояния. Если задано начальное значение, TypeScript может вывести его автоматически.


Типы useEffect

useEffect также имеет полную поддержку типов.

src/components/DataFetcher.tsx

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

// Определяем тип пользователя
interface User {
    id: number;
    name: string;
}

const DataFetcher: React.FC = () => {
    // Состояние списка пользователей
    const [users, setUsers] = useState<User[]>([]);
    // Состояние загрузки
    const [loading, setLoading] = useState<boolean>(истина);
    // Состояние ошибки
    const [error, setError] = useState<string | null>(null);

    useEffect(() => {
        // Имитировать получение данных
        fetch("/api/users")
            .then(res => res.json())
            .then(data => {
                setUsers(data);
                setLoading(false);
            })
            .catch(err => {
                setError(err.message);
                setLoading(false);
            });
    }, []);  // Пустой массив зависимостей: запускается только один раз при монтировании компонента

    if (loading) return <div>Загрузка...</div>;
    if (error) return <div>Error: {error}</div>;

    return (
        <ul>
            {users.map(user => (
                <li key={user.id}>{user.name}</li>
            ))}
        </ul>
    );
};

export default DataFetcher;

Массив зависимостей:Второй параметр useEffect — это массив зависимостей. TypeScript проверит, объявлены ли все переменные, используемые в колбэке, в этом массиве.


Обработка событий

События React имеют выделенные определения типов.

src/components/Form.tsx

import React, { useState } from "react";

const Form: React.FC = () => {
    // Состояние строкового типа
    const [name, setName] = useState<string>("");

    // Обработка события отправки формы
    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();  // Предотвратить отправку формы по умолчанию
        console.log("Отправка:", name);
    };

    // Обработка события изменения поля ввода
    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        setName(e.target.value);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                type="text"
                value={name}
                onChange={handleChange}
                placeholder="Введите имя"
            />
            <button type="submit">Отправить</button>
        </форма>
    );
};

export default Form;

Результат выполнения:

Form 组件渲染成功

Типы событий:React предоставляет типы для каждого DOM-события, такие как FormEvent, ChangeEvent, MouseEvent и т. д.


Примечания

  • React.FC:Рекомендуется использовать, чтобы получить полную поддержку типов
  • Интерфейс Props:Определяйте типы Props для каждого компонента
  • Обобщения useState:Сложные типы нужно указывать явно
  • Типы событий:Используйте типы событий, предоставляемые React

Лучшие практики:Помещайте определения типов и компоненты в один файл или централизованно управляйте ими в каталоге types


Итог

TypeScript значительно улучшает опыт разработки на React.

  • React.FC:Стандартный тип для функциональных компонентов React
  • Props:Используйте interface для определения props компонента
  • useState:Используйте обобщённые параметры для указания типа состояния
  • useEffect:Полная поддержка типов
  • События:Используйте типы событий React, чтобы избежать any

Рекомендация:Используйте TypeScript напрямую в новых проектах, это может значительно сократить ошибки времени выполнения.

Другие расширения