diff --git a/src/__tests__/react-plotly.test.js b/src/__tests__/react-plotly.test.js index d1b7646..11de80d 100644 --- a/src/__tests__/react-plotly.test.js +++ b/src/__tests__/react-plotly.test.js @@ -164,5 +164,20 @@ describe('', () => { .catch(err => done.fail(err)); }); }); + + describe('manging event handlers', () => { + test('should add an event handler when one does not already exist', (done) => { + const onRelayout = () => {}; + + createPlot({onRelayout}).then((plot) => { + const { handlers } = plot.instance(); + + expect(plot.prop('onRelayout')).toBe(onRelayout); + expect(handlers.Relayout).toBe(onRelayout); + + done(); + }); + }); + }); }); }); diff --git a/src/factory.js b/src/factory.js index ac51840..2bfb798 100644 --- a/src/factory.js +++ b/src/factory.js @@ -207,19 +207,36 @@ export default function plotComponentFactory(Plotly) { syncEventHandlers() { eventNames.forEach(eventName => { const prop = this.props['on' + eventName]; - const hasHandler = Boolean(this.handlers[eventName]); + const handler = this.handlers[eventName]; + const hasHandler = Boolean(handler); if (prop && !hasHandler) { - this.handlers[eventName] = prop; - this.el.on('plotly_' + eventName.toLowerCase(), this.handlers[eventName]); + this.addEventHandler(eventName, prop); } else if (!prop && hasHandler) { // Needs to be removed: - this.el.removeListener('plotly_' + eventName.toLowerCase(), this.handlers[eventName]); - delete this.handlers[eventName]; + this.removeEventHandler(eventName); + } else if (prop && hasHandler && prop !== handler) { + // replace the handler + this.removeEventHandler(eventName); + this.addEventHandler(eventName, prop); } }); } + addEventHandler(eventName, prop) { + this.handlers[eventName] = prop; + this.el.on(this.getPlotlyEventName(eventName), this.handlers[eventName]); + } + + removeEventHandler(eventName) { + this.el.removeListener(this.getPlotlyEventName(eventName), this.handlers[eventName]); + delete this.handlers[eventName]; + } + + getPlotlyEventName(eventName) { + return 'plotly_' + eventName.toLowerCase(); + } + render() { return (