JavaRush /Курсы /Модуль 3: React /Работа с пропсами — передача данных между компонентами

Работа с пропсами — передача данных между компонентами

Модуль 3: React
1 уровень , 6 лекция
Открыта

Разбираем работу пропсов

Вот и подошли мы к практической работе с пропсами! Пропсы (или props, сокращение от "properties") — это способ передачи данных в React-компоненты. Если представить компонент как функцию, то пропсы — это его "аргументы". Если бы компонент был автомобилем, то пропсы — это инструкция, которой вы объясняете ему, куда ехать, что везти и на какой скорости.

Пропсы позволяют компоненты делать гибкими и повторно используемыми, а это и есть одна из главных целей React.

Давайте рассмотрим ситуацию. У нас есть компонент Welcome, который выводит приветственное сообщение. Мы хотим передать в этот компонент имя пользователя, чтобы он приветствовал нас по имени. Вот пример:

// Пример передачи пропсов
type WelcomeProps = {
    name: string; // Определяем, что проп `name` должен быть строкой
};

const Welcome: React.FC<WelcomeProps> = ({ name }) => {
    return <h1>Привет, {name}!</h1>;
};

// Использование компонента с пропсами
const App = () => {
    return <Welcome name="Иван" />;
};

Что тут происходит?

  1. Мы создали интерфейс WelcomeProps для типизации пропсов.
  2. Компонент Welcome принимает проп name и рендерит его.
  3. Когда мы используем Welcome внутри компонента App, мы передаем name="Иван" как проп.

Почему пропсы важны?

Повторное использование компонентов

Представьте, что вы пишете таблицу, где каждая строка — это компонент. Вместо того чтобы писать код для каждой строки отдельно, вы просто создаете универсальный компонент строки, которому через пропсы передаете данные для рендера.

Гибкость

С помощью пропсов можно передавать не только текст или числа, но и сложные объекты, массивы, функции (да-да, функции тоже можно передавать, не удивляйтесь!).

Динамическое изменение данных через пропсы

Пропсы — это отличный способ динамически изменять данные компонентов. Например, мы можем создать компонент уведомления:

type NotificationProps = {
    message: string;
    type: "success" | "error";
};

const Notification: React.FC<NotificationProps> = ({ message, type }) => {
    const styles = {
        success: { color: "green" },
        error: { color: "red" },
    };

    return <p style={styles[type]}>{message}</p>;
};

// Использование компонента
const App = () => {
    return (
        <>
            <Notification message="Операция выполнена успешно!" type="success" />
            <Notification message="Ошибка при выполнении операции!" type="error" />
        </>
    );
};

В этом примере пропсы message и type задают текст и стиль уведомления.

Композиция компонентов с пропсами

Пропсы позволяют "встраивать" компоненты друг в друга. Например:

// Компонент кнопки
type ButtonProps = {
    onClick: () => void;
    label: string;
};

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

// Компонент карточки
type CardProps = {
    title: string;
    onButtonClick: () => void;
};

const Card: React.FC<CardProps> = ({ title, onButtonClick }) => {
    return (
        <div>
            <h2>{title}</h2>
            <Button onClick={onButtonClick} label="Нажми меня" />
        </div>
    );
};

// Использование компонентов
const App = () => {
    const handleClick = () => {
        alert("Кнопка нажата!");
    };

    return <Card title="Заголовок карточки" onButtonClick={handleClick} />;
};

Здесь компонент Card использует компонент Button и передает ему пропсы. Таким образом, мы можем строить из маленьких блоков сложные интерфейсы.

Обработка необязательных пропсов

В жизни не всегда всё обязательно. Так и с пропсами. Иногда компонент может работать без некоторых из них. Для этого можно использовать ? в интерфейсе:

type WelcomeProps = {
    name?: string;
};

const Welcome: React.FC<WelcomeProps> = ({ name }) => {
    return <h1>Привет, {name ?? "Гость"}!</h1>;
};

// Использование компонента
const App = () => {
    return (
        <>
            <Welcome name="Иван" />
            <Welcome />
        </>
    );
};

Здесь проп name является необязательным. Если он не передан, компонент рендерит текст "Гость".

Пропсы — это однонаправленный поток данных

React следует принципу однонаправленного потока данных (unidirectional data flow). Это значит, что данные передаются из родительского компонента в дочерний, но не наоборот. Попытка изменить проп внутри дочернего компонента приведёт к ошибке.

Как это выглядит?

const Parent = () => {
    const [name, setName] = useState("Иван");

    return <Child name={name} />;
};

const Child: React.FC<{ name: string }> = ({ name }) => {
    return <h1>Привет, {name}!</h1>;
};

Данные name определяются в родительском компоненте Parent и передаются дочернему компоненту Child. Если вы хотите, чтобы дочерний компонент мог как-то влиять на данные, передавайте функцию обратного вызова (callback) в пропсах.

Передача функций через пропсы

Вы можете передавать не только данные, но и функции:

type CounterProps = {
    onIncrement: () => void;
    onDecrement: () => void;
};

const Counter: React.FC<CounterProps> = ({ onIncrement, onDecrement }) => {
    return (
        <div>
            <button onClick={onDecrement}>-</button>
            <button onClick={onIncrement}>+</button>
        </div>
    );
};

const App = () => {
    const handleIncrement = () => {
        console.log("Увеличить");
    };

    const handleDecrement = () => {
        console.log("Уменьшить");
    };

    return <Counter onIncrement={handleIncrement} onDecrement={handleDecrement} />;
};

Типичные ошибки и подводные камни

  1. Не забывайте о типизации! Пропсы без типизации — это открытая дверь для ошибок. Убедитесь, что вы описываете интерфейсы для всех данных, которые передаете.

  2. Пропсы неизменяемы (immutable). Если вы хотите изменить данные, переданные через пропсы, измените их в родительском компоненте и передайте обновленные данные.

  3. Не передавайте слишком много пропсов. Если компонент принимает более 5–7 пропсов, это может говорить о плохой архитектуре. В таких случаях стоит использовать композицию или подумать о контексте.

Применение пропсов в реальной жизни

Пропсы используются в каждом React-приложении. Они позволяют создавать гибкие компоненты, которые вы можете повторно использовать в разных частях приложения. На собеседованиях часто просят написать компонент с пропсами, чтобы проверить, как вы работаете с потоками данных.

Не важно, создаете ли вы форму, таблицу или карточку продукта в интернет-магазине — пропсы — это ваши друзья.

Теперь, когда вы знаете, как работать с пропсами, вы готовы перейти к следующему важному шагу — типизации пропсов, чтобы сделать ваш код ещё более надёжным. 🎉

1
Задача
Модуль 3: React, 1 уровень, 6 лекция
Недоступна
Передача текстового пропса
Передача текстового пропса
1
Задача
Модуль 3: React, 1 уровень, 6 лекция
Недоступна
Компонент с переданной функцией-обработчиком
Компонент с переданной функцией-обработчиком
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ