5.1 Типизация пропсов
React — это библиотека для создания пользовательских интерфейсов, которая использует компоненты как строительные блоки. TypeScript добавляет к этому статическую типизацию, что помогает разработчикам избегать ошибок и улучшает автодополнение и рефакторинг кода в редакторах.
Типизация пропсов (props) в React компонентах с использованием TypeScript позволяет обеспечить корректность передаваемых данных и улучшить автодополнение в редакторах кода.
Функциональные компоненты
Функциональные компоненты в React — это компоненты, которые являются функциями, возвращающими JSX. Для типизации пропсов в функциональных компонентах используется интерфейс или тип.
Пример простого функционального компонента с типизированными пропсами:
import React from 'react';
// Интерфейс для типизации пропсов компонента Greeting
interface GreetingProps {
name: string; // Обязательный пропс
age?: number; // Необязательный пропс
}
// Компонент Greeting, который принимает пропсы GreetingProps
const Greeting: React.FC<GreetingProps> = ({ name, age }) => {
return (
<div>
<h1>Hello, {name}!</h1> {/* Приветствие с именем */}
{age && <p>You are {age} years old.</p>} {/* Вывод возраста, если он передан */}
</div>
);
};
// Экспорт компонента Greeting для использования в других частях приложения
export default Greeting;
В этом примере мы определили интерфейс GreetingProps для типизации пропсов компонента Greeting. Пропс age необязательный.
Классовые компоненты
Классовые компоненты — это компоненты, которые создаются как классы, наследующие от React.Component. Типизация пропсов в классовых компонентах также осуществляется с помощью интерфейсов или типов.
Пример классового компонента с типизированными пропсами:
import React, { Component } from 'react';
// Интерфейс для типизации пропсов компонента Welcome
interface WelcomeProps {
message: string; // Обязательный пропс
}
// Компонент Welcome, который наследует Component с пропсами WelcomeProps
class Welcome extends Component<WelcomeProps> {
// Метод render для отображения компонента
render() {
return <h1>{this.props.message}</h1>;
}
}
// Экспорт компонента Welcome для использования в других частях приложения
export default Welcome;
В этом примере мы определили интерфейс WelcomeProps для типизации пропсов компонента Welcome.
5.2 Типизация состояния
Состояние (state) в React компонентах используется для управления динамическими данными. Типизация состояния помогает предотвратить ошибки при работе с состоянием и улучшает автодополнение.
Классовые компоненты со состоянием
Для типизации состояния в классовых компонентах используется второй параметр в обобщении React.Component.
Пример классового компонента с типизированным состоянием:
import React, { Component } from 'react';
// Интерфейс для типизации пропсов компонента Counter
interface CounterProps {
initialCount: number; // Начальное значение счетчика
}
// Интерфейс для состояния компонента Counter
interface CounterState {
count: number; // Текущее значение счетчика
}
// Компонент Counter, который наследует Component с пропсами CounterProps и состоянием CounterState
class Counter extends Component<CounterProps, CounterState> {
// Конструктор компонента
constructor(props: CounterProps) {
super(props);
this.state = {
count: props.initialCount // Инициализация состояния с начальным значением
};
}
// Метод для увеличения счетчика
increment = () => {
this.setState({ count: this.state.count + 1 });
};
// Метод для уменьшения счетчика
decrement = () => {
this.setState({ count: this.state.count - 1 });
};
// Метод render для отображения компонента
render() {
return (
<div>
<h1>Count: {this.state.count}</h1>
<button onClick={this.increment}>Increment</button>
<button onClick={this.decrement}>Decrement</button>
</div>
);
}
}
// Экспорт компонента Counter для использования в других частях приложения
export default Counter;
В этом примере мы определили интерфейс CounterState для типизации состояния компонента Counter.
Функциональные компоненты с хуками
React хуки, такие как useState и useReducer, позволяют управлять состоянием в функциональных компонентах. Типизация состояния с хуками также осуществляется с помощью интерфейсов или типов.
Пример функционального компонента с типизированным состоянием с использованием useState:
import React, { useState } from 'react';
interface ToggleProps {
initialOn: boolean;
}
const Toggle: React.FC<ToggleProps> = ({ initialOn }) => {
const [isOn, setIsOn] = useState<boolean>(initialOn);
const toggle = () => {
setIsOn(!isOn);
};
return (
<div>
<p>{isOn ? 'On' : 'Off'}</p>
<button onClick={toggle}>Toggle</button>
</div>
);
};
export default Toggle;
В этом примере мы используем хук useState для управления состоянием компонента Toggle и типизируем его состояние как boolean.
Пример функционального компонента с типизированным состоянием с использованием useReducer:
import React, { useReducer } from 'react';
interface CounterState {
count: number;
}
type CounterAction =
| { type: 'increment' }
| { type: 'decrement' };
const initialState: CounterState = { count: 0 };
function counterReducer(state: CounterState, action: CounterAction): CounterState {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
const Counter: React.FC = () => {
const [state, dispatch] = useReducer(counterReducer, initialState);
return (
<div>
<h1>Count: {state.count}</h1>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
};
export default Counter;
В этом примере мы используем хук useReducer для управления состоянием компонента Counter и типизируем состояние и действия с помощью интерфейсов и типов.
5.3 Продвинутые типы
Типизация в TypeScript позволяет создавать сложные и гибкие типы для более точного определения структуры данных.
Union и Intersection Types
Пример использования Union Types:
// Тип для возможных статусов
type Status = 'loading' | 'success' | 'error';
// Интерфейс для типизации пропсов компонента StatusMessage
interface StatusMessageProps {
status: Status; // Текущий статус
}
// Компонент StatusMessage, который принимает пропсы StatusMessageProps
const StatusMessage: React.FC<StatusMessageProps> = ({ status }) => {
return (
<div>
{/* Условный рендеринг в зависимости от статуса */}
{status === 'loading' && <p>Loading...</p>}
{status === 'success' && <p>Success!</p>}
{status === 'error' && <p>Error!</p>}
</div>
);
};
// Экспорт компонента StatusMessage для использования в других частях приложения
export default StatusMessage;
Пример использования Intersection Types:
// Интерфейс для пропсов загрузки
interface LoadingProps {
loading: boolean; // Флаг загрузки
}
// Интерфейс для пропсов данных
interface DataProps {
data: string[]; // Массив данных
}
// Комбинированный тип, объединяющий LoadingProps и DataProps
type CombinedProps = LoadingProps & DataProps;
// Компонент DataLoader, который принимает комбинированные пропсы
const DataLoader: React.FC<CombinedProps> = ({ loading, data }) => {
return (
<div>
{loading ? <p>Loading...</p> : <ul>{data.map((item) => <li key={item}>{item}</li>)}</ul>}
</div>
);
};
// Экспорт компонента DataLoader для использования в других частях приложения
export default DataLoader;
Более подробно со взаимодействием TypeScript вы познакомитесь в модуле 3, когда мы начнем изучать React.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ