Урок 04

Компоненты и пропсы

Компонент — это функция, которая возвращает JSX. Компоненты — это переиспользуемые блоки: кнопка, карточка, форма, страница.

Функциональный компонент

function Welcome() {
    return <h1>Привет</h1>;
}

Имя компонента пишется с большой буквы. Это отличает его от обычных HTML-тегов.

Использование

function App() {
    return (
        <div>
            <Welcome />
            <Welcome />
            <Welcome />
        </div>
    );
}

Пропсы

Пропсы — это аргументы компонента. Через них передаются данные от родителя к ребёнку.

type WelcomeProps = {
    name: string;
};

function Welcome({ name }: WelcomeProps) {
    return <h1>Привет, {name}</h1>;
}

// Использование
<Welcome name="Алиса" />
<Welcome name="Боб" />

Несколько пропсов

type UserCardProps = {
    name: string;
    age: number;
    email: string;
};

function UserCard({ name, age, email }: UserCardProps) {
    return (
        <div>
            <h2>{name}</h2>
            <p>Возраст: {age}</p>
            <p>Email: {email}</p>
        </div>
    );
}

<UserCard name="Алиса" age={25} email="alice@example.com" />

Строки передаются в кавычках, остальное — в фигурных скобках.

Дети (children)

Особый проп children — это содержимое между открывающим и закрывающим тегами:

type CardProps = {
    children: React.ReactNode;
};

function Card({ children }: CardProps) {
    return <div className="card">{children}</div>;
}

<Card>
    <h2>Заголовок</h2>
    <p>Текст внутри карточки</p>
</Card>

React.ReactNode — это тип, который принимает любой JSX: строку, элемент, массив, null.

Значения по умолчанию

type ButtonProps = {
    label?: string;
    variant?: 'primary' | 'secondary';
};

function Button({ label = 'Кнопка', variant = 'primary' }: ButtonProps) {
    return <button className={variant}>{label}</button>;
}

Пропсы-функции

Через пропсы передают не только данные, но и функции:

type ButtonProps = {
    onClick: () => void;
    children: React.ReactNode;
};

function Button({ onClick, children }: ButtonProps) {
    return <button onClick={onClick}>{children}</button>;
}

<Button onClick={() => alert('Клик')}>Нажми</Button>

Пропсы только для чтения

React не разрешает изменять пропсы внутри компонента. Если нужно изменить — родитель передаёт новое значение.

function Bad({ count }) {
    count = 10; // ошибка: пропсы только для чтения
}

Деструктуризация в аргументах

Вместо props.name используют деструктуризацию:

function Welcome({ name, age }: WelcomeProps) {
    return <p>{name}, {age}</p>;
}

Это короче и сразу видно, какие пропсы компонент использует.

Композиция

Компоненты вкладываются друг в друга. Мелкие компоненты собираются в крупные:

function Avatar({ src }: { src: string }) {
    return <img src={src} className="avatar" />;
}

function UserInfo({ user }: { user: User }) {
    return (
        <div>
            <Avatar src={user.avatar} />
            <span>{user.name}</span>
        </div>
    );
}

Итоги

  • Компонент — функция с большой буквы, возвращающая JSX
  • Пропсы — аргументы, передаются от родителя
  • children — особый проп для вложенного контента
  • Типизация через type или interface
  • Пропсы только для чтения