Я создаю и слушаю обычные DOM CustomEvent
для связи с родительскими узлами:
У ребенка:
var moveEvent = new CustomEvent('the-graph-group-move', {
detail: {
nodes: this.props.nodes,
x: deltaX,
y: deltaY
},
bubbles: true
});
this.getDOMNode().dispatchEvent(moveEvent);
В родительском:
componentDidMount: function () {
this.getDOMNode().addEventListener("the-graph-group-move", this.moveGroup);
},
Это работает, но есть ли способ, специфичный для React, который был бы лучше?
<Child onCustomEvent={this.handleCustomEvent} />
. В React нет поддержки пользовательских событий с всплыванием.Ответы:
Как указано выше:
Абстракция реактивного программирования ортогональна:
Вместо этого философия React основана на шаблоне Command:
Рекомендации
источник
a class of debugging problems where you don't know what triggers some code because of a long chain of events triggering other events
. Шаблон команды с потоком данных в одном направлении , являются React философии.вы можете написать простой сервис, а затем использовать его
/** eventsService */ module.exports = { callbacks: {}, /** * @param {string} eventName * @param {*} data */ triggerEvent(eventName, data = null) { if (this.callbacks[eventName]) { Object.keys(this.callbacks[eventName]).forEach((id) => { this.callbacks[eventName][id](data); }); } }, /** * @param {string} eventName name of event * @param {string} id callback identifier * @param {Function} callback */ listenEvent(eventName, id, callback) { this.callbacks[eventName][id] = callback; }, /** * @param {string} eventName name of event * @param {string} id callback identifier */ unlistenEvent(eventName, id) { delete this.callbacks[eventName][id]; }, };
пример (то же самое для запуска)
import eventsService from '../../../../services/events'; export default class FooterMenu extends Component { componentWillMount() { eventsService .listenEvent('cart', 'footer', this.cartUpdatedListener.bind(this)); } componentWillUnmount() { eventsService .unlistenEvent('cart', 'footer'); } cartUpdatedListener() { console.log('cart updated'); } }
источник
Вы можете всплывать событиями через обратные вызовы, передаваемые через контексты: [CodePen]
import * as React from 'react'; const MyEventContext = React.createContext(() => {}); const MyEventBubbleContext = ({children, onMyEvent}) => { const bubbleEvent = React.useContext(MyEventContext); const handleMyEvent = React.useCallback((...args) => { // stop propagation if handler returns false if (onMyEvent(...args) !== false) { // bubble the event bubbleEvent(...args); } }, [onMyEvent]); return ( <MyEventContext.Provider value={handleMyEvent}> {children} </MyEventContext.Provider> ); }; const MyComponent = () => ( <MyEventBubbleContext onMyEvent={e => console.log('grandparent got event: ', e)}> <MyEventBubbleContext onMyEvent={e => console.log('parent got event: ', e)}> <MyEventContext.Consumer> {onMyEvent => <button onClick={onMyEvent}>Click me</button>} </MyEventContext.Consumer> </MyEventBubbleContext> </MyEventBubbleContext> ); export default MyComponent;
источник
Я нашел еще один, который тоже вполне разумен, особенно если сверлить отверстия от родителя к ребенку к ребенку уже становится обременительным. Он назвал это менее простым общением. Вот ссылка:
https://github.com/ryanflorence/react-training/blob/gh-pages/lessons/04-less-simple-communication.md
источник
Возможное решение, если вы абсолютно необходимо прибегнуть к шаблону Observer в приложении ReactJs, вы можете захватить обычное событие. Например, если вы хотите, чтобы клавиша удаления вызывала событие,
<div>
помеченное для удаления, вы можете<div>
прослушивать событие нажатия клавиши, которое будет вызываться customEvent. Захватите keydown на теле иcustomEvent
отправьте событие keydown для выбранного<div>
. Обмен на случай, если это кому-то поможет.источник
Центральное хранилище [Redux], которое распределяет состояние клиентам, которое затем «отправляет» состояние обратно в хранилище, также похоже на шаблон наблюдателя. Способ публикации / подписки только хуже из-за явных (хрупких?) Накладных расходов, связанных с путями реквизитов / событий. Чтобы взломать иерархию, React предоставляет контекст (шаблон поставщика) или наблюдаемые библиотеки, которые воняют. Например, MobX, который вводит новые декораторы @observable, или Vue, который вводит новый синтаксис шаблона «v-if». События - это основной способ работы цикла событий DOM и javascript, так почему бы и нет? Я думаю, это сделали сатанисты. Смешно
источник
Я понимаю, что этот вопрос уже довольно старый, но этот ответ может кому-то помочь. Я написал прагму JSX для React, которая добавляет декларативное настраиваемое событие: jsx-native-events .
По сути, вы просто используете
onEvent<EventName>
шаблон для отслеживания событий.источник