Как передать данные из родительского компонента в дочерний?react-7

Основные методы передачи данных

1. Через props

Самый простой и часто используемый метод передачи данных.

Родительский компонент:

function ParentComponent() {
  const [message, setMessage] = useState('Привет от родителя!');
  const user = { name: 'Алексей', age: 30 };

  return (
    <ChildComponent
      text={message}
      userData={user}
      onUpdate={setMessage}
    />
  );
}

Дочерний компонент:

function ChildComponent({ text, userData, onUpdate }) {
  return (
    <div>
      <p>Полученный текст: {text}</p>
      <p>Пользователь: {userData.name}, {userData.age} лет</p>
      <button onClick={() => onUpdate('Новое сообщение')}>
        Обновить
      </button>
    </div>
  );
}

2. Через children

Полезно для композиции компонентов.

Родительский компонент:

function ParentComponent() {
  return (
    <Container>
      <h1>Это будет передано как children</h1>
      <p>Любое содержимое</p>
    </Container>
  );
}

Дочерний компонент:

function Container({ children }) {
  return <div className="wrapper">{children}</div>;
}

3. Через Context API

Для передачи данных через много уровней без явного пробрасывания.

Создание контекста:

const UserContext = createContext();

function App() {
  const [user, setUser] = useState({ name: 'Мария', role: 'admin' });

  return (
    <UserContext.Provider value={{ user, setUser }}>
      <ParentComponent />
    </UserContext.Provider>
  );
}

Использование в дочернем компоненте:

function DeepChildComponent() {
  const { user, setUser } = useContext(UserContext);

  return <p>Пользователь: {user.name}</p>;
}

Передача функций

Важный частный случай передачи данных - передача функций для обратной связи.

Родительский компонент:

function ParentComponent() {
  const handleDataFromChild = (data) => {
    console.log('Данные от ребенка:', data);
  };

  return <ChildComponent sendData={handleDataFromChild} />;
}

Дочерний компонент:

function ChildComponent({ sendData }) {
  const clickHandler = () => {
    sendData({ message: 'Привет родителю!' });
  };

  return <button onClick={clickHandler}>Отправить данные</button>;
}

Особенности передачи разных типов данных

  1. Примитивы (строки, числа, булевы):

    <ChildComponent name="Иван" age={25} isActive={true} />
    
  2. Объекты и массивы:

    <ChildComponent
      user={{ name: 'Ольга', id: 123 }}
      items={['Яблоко', 'Груша']}
    />
    
  3. JSX-элементы:

    <ChildComponent header={<h1>Заголовок</h1>} />
    

Рекомендации по передаче данных

  1. Избегайте prop drilling (глубокого пробрасывания):

    • Используйте Context API или state-менеджеры для глубокой передачи
  2. Документируйте props:

    • Используйте PropTypes или TypeScript
    ChildComponent.propTypes = {
      text: PropTypes.string.isRequired,
      onUpdate: PropTypes.func
    };
    
  3. Оптимизируйте передачу объектов:

    • Для больших объектов используйте useMemo, чтобы избежать лишних ререндеров
    const memoizedUser = useMemo(() => ({ name, age }), [name, age]);
    

Резюмируем

  1. Основные способы передачи:

    • Через props (рекомендуется для прямой передачи)
    • Через children (для композиции компонентов)
    • Через Context API (для глобальных данных)
  2. Что можно передавать:

    • Любые JavaScript-значения
    • Функции для обратной связи
    • React-элементы и компоненты
  3. Лучшие практики:

    • Минимизируйте количество передаваемых props
    • Избегайте мутации полученных данных
    • Используйте типизацию (TypeScript/PropTypes)

Совет: Для сложных приложений комбинируйте разные подходы - простые props для близких компонентов, Context API для глобальных данных, state-менеджеры для сложных состояний.