Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Передача данных между компонентами в React
В React существует несколько способов передачи данных между компонентами. Выбор метода зависит от типа связи и архитектуры приложения.
1. Props (родитель -> потомок)
Это базовый и наиболее часто используемый способ:
// Родительский компонент
const Parent = () => {
const data = 'Привет из родителя';
return <Child message={data} />;
};
// Дочерний компонент
const Child = ({ message }) => (
<div>{message}</div>
);
2. Props drilling (передача через промежуточные компоненты)
// Уровень 1
const Level1 = () => {
const data = 'Важная информация';
return <Level2 data={data} />;
};
// Уровень 2 (просто пробрасываем далее)
const Level2 = ({ data }) => {
return <Level3 data={data} />;
};
// Уровень 3 (используем)
const Level3 = ({ data }) => {
return <div>{data}</div>;
};
// Проблема: много промежуточных компонентов
// Решение: использовать Context API
3. Context API (глобальное состояние)
import { createContext, useContext, useState } from 'react';
// 1. Создаем контекст
const UserContext = createContext();
// 2. Создаем провайдер
const UserProvider = ({ children }) => {
const [user, setUser] = useState({ name: 'Алексей', age: 25 });
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
};
// 3. Используем контекст в компоненте
const UserProfile = () => {
const { user, setUser } = useContext(UserContext);
return (
<div>
<p>Имя: {user.name}</p>
<button onClick={() => setUser({ ...user, name: 'Виктория' })}>
Изменить имя
</button>
</div>
);
};
// 4. Обертываем приложение провайдером
const App = () => (
<UserProvider>
<UserProfile />
</UserProvider>
);
4. Callback функции (потомок -> родитель)
// Родитель
const Parent = () => {
const [value, setValue] = useState('');
const handleChildClick = (data) => {
console.log('Данные от ребенка:', data);
setValue(data);
};
return (
<div>
<p>Значение: {value}</p>
<Child onSendData={handleChildClick} />
</div>
);
};
// Ребенок
const Child = ({ onSendData }) => (
<button onClick={() => onSendData('Привет из ребенка')}>
Отправить данные
</button>
);
5. State management (Zustand, Redux, Recoil)
// Пример с Zustand (простой и популярный)
import { create } from 'zustand';
const useUserStore = create((set) => ({
user: { name: 'Алексей' },
updateUser: (newUser) => set({ user: newUser })
}));
// Компонент 1
const Component1 = () => {
const user = useUserStore((state) => state.user);
return <div>Пользователь: {user.name}</div>;
};
// Компонент 2
const Component2 = () => {
const updateUser = useUserStore((state) => state.updateUser);
return (
<button onClick={() => updateUser({ name: 'Виктория' })}>
Обновить
</button>
);
};
6. Рефы (для доступа к DOM)
import { useRef } from 'react';
const Parent = () => {
const inputRef = useRef(null);
const handleFocus = () => {
inputRef.current.focus();
};
return (
<div>
<Child ref={inputRef} />
<button onClick={handleFocus}>Фокус на поле</button>
</div>
);
};
const Child = React.forwardRef((props, ref) => (
<input ref={ref} placeholder="Введите текст" />
));
7. URL параметры и query string
import { useNavigate, useSearchParams } from 'react-router-dom';
// Передача через URL
const Component1 = () => {
const navigate = useNavigate();
const handleClick = () => {
navigate('/profile?id=123&name=alex');
};
return <button onClick={handleClick}>Перейти</button>;
};
// Получение из URL
const Component2 = () => {
const [searchParams] = useSearchParams();
const id = searchParams.get('id');
const name = searchParams.get('name');
return <div>ID: {id}, Имя: {name}</div>;
};
8. Событие обновления (Event Bus)
// Простой event bus
class EventBus {
constructor() {
this.events = {};
}
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
emit(event, data) {
if (this.events[event]) {
this.events[event].forEach((callback) => callback(data));
}
}
}
const bus = new EventBus();
// Компонент 1 (слушатель)
const ListenerComponent = () => {
const [data, setData] = useState(null);
useEffect(() => {
bus.on('update', setData);
return () => bus.off('update', setData);
}, []);
return <div>Данные: {data}</div>;
};
// Компонент 2 (отправитель)
const EmitterComponent = () => {
const handleClick = () => {
bus.emit('update', 'Новые данные');
};
return <button onClick={handleClick}>Отправить</button>;
};
Сравнение методов
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Props | Простой, явный поток данных | Props drilling при глубокой иерархии | Родитель -> потомок, соседи через родителя |
| Context | Избегает props drilling | Может вызвать лишние ре-рендеры | Глобальные данные (тема, язык, юзер) |
| Callback | Обратная связь | Немного запутанно | Потомок -> родитель |
| State manager | Масштабируемость | Больше кода | Сложное состояние, много компонентов |
| URL params | Сохраняется в истории | Небезопасно для конфиденциальных данных | Фильтры, поиск, навигация |
Рекомендации
- Для близких компонентов - используй props
- Для отдаленных компонентов - Context API
- Для сложного состояния - Zustand, Redux или Recoil
- Для фильтров и поиска - URL параметры
- Избегай props drilling - лучше используй Context
- Не переусложняй - KISS принцип