В React передача данных из дочернего компонента в родительский является общим требованием. С появлением React Hooks управление состоянием и связью между компонентами стало еще более эффективным. В этом сообщении блога мы рассмотрим пять эффективных методов выполнения этой задачи с помощью React Hooks. Мы углубимся в примеры кода и будем использовать разговорный язык, чтобы сделать концепции легко понятными. Давайте начнем!
- Функции обратного вызова.
Один из самых простых способов отправить данные из дочернего компонента в его родительский — использовать функции обратного вызова. Вот пример:
Родительский компонент:
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
const [data, setData] = useState('');
const handleDataChange = (newData) => {
setData(newData);
};
return (
<div>
<h2>Parent Component</h2>
<ChildComponent onDataChange={handleDataChange} />
<p>Received data: {data}</p>
</div>
);
};
export default ParentComponent;
Дочерний компонент:
import React from 'react';
const ChildComponent = ({ onDataChange }) => {
const sendDataToParent = () => {
const newData = 'Hello from child!';
onDataChange(newData);
};
return (
<div>
<h3>Child Component</h3>
<button onClick={sendDataToParent}>Send Data</button>
</div>
);
};
export default ChildComponent;
В этом примере дочерний компонент ChildComponentполучает функцию обратного вызова onDataChangeв качестве реквизита от своего родительского компонента ParentComponent. Когда кнопка нажимается в дочернем компоненте, она вызывает функцию sendDataToParent, которая вызывает обратный вызов onDataChangeс новыми данными.
- Context API.
Еще один мощный метод передачи данных от дочернего компонента к родительскому — использование Context API. Вот пример:
import React, { createContext, useContext, useState } from 'react';
const DataContext = createContext();
const ParentComponent = () => {
const [data, setData] = useState('');
const handleDataChange = (newData) => {
setData(newData);
};
return (
<div>
<h2>Parent Component</h2>
<DataContext.Provider value={handleDataChange}>
<ChildComponent />
</DataContext.Provider>
<p>Received data: {data}</p>
</div>
);
};
const ChildComponent = () => {
const onDataChange = useContext(DataContext);
const sendDataToParent = () => {
const newData = 'Hello from child!';
onDataChange(newData);
};
return (
<div>
<h3>Child Component</h3>
<button onClick={sendDataToParent}>Send Data</button>
</div>
);
};
export default ParentComponent;
В этом примере мы создаем DataContextс помощью функции createContextи предоставляем функцию handleDataChangeв качестве значения. Дочерний компонент ChildComponentиспользует хук useContextдля доступа к функции onDataChangeиз контекста. При нажатии кнопки вызывается функция sendDataToParent, передающая новые данные родительскому компоненту.
- Пользовательские перехватчики.
Пользовательские перехватчики позволяют нам инкапсулировать логику и распределять ее между компонентами. Мы можем создать собственный крючок для передачи данных от дочернего компонента к родительскому. Вот пример:
import React, { useState } from 'react';
const useDataPassing = () => {
const [data, setData] = useState('');
const handleDataChange = (newData) => {
setData(newData);
};
return [data, handleDataChange];
};
const ParentComponent = () => {
const [data, handleDataChange] = useDataPassing();
return (
<div>
<h2>Parent Component</h2>
<ChildComponent onDataChange={handleDataChange} />
<p>Received data: {data}</p>
</div>
);
};
const ChildComponent = ({ onDataChange }) => {
const sendDataToParent = () => {
const newData = 'Hello from child!';
onDataChange(newData);
};
return (
<div>
<h3>Child Component</h3>
<button onClick={sendDataToParent}>Send Data</button>
</div>
);
};
export default ParentComponent;
В этом примере мы определяем специальный хук useDataPassing, который возвращает состояние dataи функцию handleDataChange. Родительский компонент ParentComponentиспользует пользовательский хук для получения функций dataи handleDataChange. Дочерний компонент ChildComponentполучает функцию handleDataChangeв качестве реквизита и вызывает ее с новыми данными при нажатии кнопки.
- EventEmitter:
Если вы предпочитаете подход, основанный на событиях, вы можете использовать генератор событий для передачи данных от дочернего компонента к родительскому. Вот пример использования библиотекиeventemitter3:
import React, { useEffect } from 'react';
import { EventEmitter } from 'eventemitter3';
const emitter = new EventEmitter();
const ParentComponent = () => {
useEffect(() => {
const handleDataChange = (newData) => {
console.log('Received data:', newData);
};
emitter.on('dataChange', handleDataChange);
return () => {
emitter.off('dataChange', handleDataChange);
};
}, []);
return (
<div>
<h2>Parent Component</h2>
<ChildComponent />
</div>
);
};
const ChildComponent = () => {
const sendDataToParent = () => {
const newData = 'Hello from child!';
emitter.emit('dataChange', newData);
};
return (
<div>
<h3>Child Component</h3>
<button onClick={sendDataToParent}>Send Data</button>
</div>
);
};
export default ParentComponent;
В этом примере мы создаем экземпляр класса EventEmitter, предоставленный библиотекой eventemitter3. Родительский компонент ParentComponentпрослушивает событие 'dataChange'и обрабатывает его, регистрируя полученные данные. Дочерний компонент ChildComponentгенерирует событие 'dataChange'с новыми данными при нажатии кнопки.
- Redux или React Context с редукторами:
Если вы уже используете Redux или React Context с редукторами в своем приложении, вы можете использовать их для передачи данных от дочерних компонентов к родительским. Диспетчеризируя действия или обновляя состояние через редукторы, вы можете добиться такого взаимодействия. Вот пример использования Redux:
// Redux setup and configuration
// Parent component
const ParentComponent = () => {
const data = useSelector((state) => state.data);
return (
<div>
<h2>Parent Component</h2>
<ChildComponent />
<p>Received data: {data}</p>
</div>
);
};
// Child component
const ChildComponent = () => {
const dispatch = useDispatch();
const sendDataToParent = () => {
const newData = 'Hello from child!';
dispatch({ type: 'UPDATE_DATA', payload: newData });
};
return (
<div>
<h3>Child Component</h3>
<button onClick={sendDataToParent}>Send Data</button>
</div>
);
};
export default ParentComponent;
В этом примере родительский компонент ParentComponentиспользует хук useSelectorдля доступа к dataиз хранилища Redux. Дочерний компонент ChildComponentиспользует хук useDispatchдля отправки действия с новыми данными для обновления хранилища Redux.
В этом сообщении блога мы рассмотрели пять эффективных методов передачи данных от дочерних компонентов к родительским с помощью React Hooks. Мы рассмотрели функции обратного вызова, Context API, пользовательские перехватчики, генераторы событий и контекст Redux/React с редукторами. Эти методы предоставляют различные варианты в зависимости от требований и предпочтений вашего проекта. Реализуя эти методы, вы можете улучшить взаимодействие и поток данных между вашими компонентами React. Приятного кодирования!