I'm making and listening for normal DOM CustomEvent
s to communicate to parent nodes:
In child:
var moveEvent = new CustomEvent('the-graph-group-move', { detail: { nodes: this.props.nodes, x: deltaX, y: deltaY }, bubbles: true }); this.getDOMNode().dispatchEvent(moveEvent);
In parent:
componentDidMount: function () { this.getDOMNode().addEventListener("the-graph-group-move", this.moveGroup); },
This works, but is there a React-specific way that would be better?
As noted above:
The React way would be to pass callbacks down to children explicitly via props — . There's no support for custom events w/ bubbling in React.
The reactive programming abstraction is orthogonal:
Programming interactive systems by means of the observer pattern is hard and error-prone yet is still the implementation standard in many production environments. We present an approach to gradually deprecate observers in favor of reactive programming abstractions. Several library layers help programmers to smoothly migrate existing code from callbacks to a more declarative programming model.
The React philosophy is based on the Command pattern instead:
References
you can write a simple service and then use it
/** 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]; }, };
example (same for triggering)
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'); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With