Я делаю и слушаю обычный 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);
},
Это работает, но есть ли конкретный вариант, который будет лучше?
Ответ 1
Как отмечено выше:
Реагирование будет заключаться в том, чтобы передать обратные вызовы детям напрямую через реквизиты -. Там нет поддержки пользовательских событий с пузырьками в React.
Абстракция реактивного программирования ортогональна:
Программирование интерактивных систем с помощью шаблона наблюдателя является трудным и подверженным ошибкам, но по-прежнему является стандартом внедрения во многих производственных средах. Мы представляем подход к постепенному обесцениванию наблюдателей в пользу абстракций реактивного программирования. Несколько слоев библиотеки помогают программистам плавно переносить существующий код из обратных вызовов на более декларативную модель программирования.
Философия React основана на шаблоне Command:
![введите описание изображения здесь]()
Ссылки
Ответ 2
Есть еще один, который я нашел, что вполне разумно, особенно если бурение отверстий от родительского до ребенка к ребенку уже становится громоздким. Он назвал его менее простым. Здесь ссылка:
https://github.com/ryanflorence/react-training/blob/gh-pages/lessons/04-less-simple-communication.md
Ответ 3
Вы можете написать простой сервис, а затем использовать его
/** 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');
}
}
Ответ 4
Возможное решение, если вы абсолютно должны обратиться к шаблону Observer в приложении ReactJs, вы можете захватить нормальное событие. Например, если вы хотите, чтобы ключ удаления вызывал <div>
, который помечен для удаления, вы могли бы прослушать <div>
событие keydown, которое будет вызываться customEvent. Ловушка на клавиатуре и отправьте событие customEvent
keydown на выбранном <div>
. Совместное использование в случае, если это поможет кому-то.
Ответ 5
Вы можете всплывать события через обратные вызовы, передаваемые через контексты: [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;
Ответ 6
Центральное хранилище [Redux], которое распределяет состояние по клиентам, которое затем "отправляет" состояние обратно в хранилище, похоже на шаблон наблюдателя. Способ делать публикацию/подписку только хуже из-за явных (хрупких?) Накладных расходов, соединяющих пути реквизитов/событий. Чтобы разобраться в иерархии, React предоставляет контекст (шаблон поставщика) или наблюдаемые библиотеки, которые воняют. Как MobX, который вводит новые декораторы @observable, или Vue, который вводит новый синтаксис шаблона "v-if". Событие - это основной способ работы цикла событий DOM и JavaScript, так почему бы и нет? Я думаю, что сатанисты сделали это. Лол
Ответ 7
Я понимаю, что этот вопрос уже довольно старый, но этот ответ все еще может кому-то помочь. Я написал JSX-прагму для React, которая добавляет декларативное настраиваемое событие: jsx-native-events.
По сути, вы просто используете onEvent<EventName>
для отслеживания событий.
<some-custom-element onEventSomeEvent={ callback }></some-custom-element>