msqar
msqar

Reputation: 3040

StrictMode causing double event subscription in React

I have an EventEmitter in my ReactJS app that has dispatch & subscribe functions for overall component communication within my site. React StrictMode is causing of course, my views to re-render twice, including its constructors. Within the Home view, I'm subscribing to an specific event attached to the corresponding callback, so in development mode, this event is being triggered twice. It's pretty annoying.

This is the EventEmitter:

export const EventEmitter = {
    events: {},
    dispatch(event, data) {
        if (!this.events[event]) return;
        this.events[event].forEach(callback => callback(data));
    },
    subscribe(event, callback) {
        if (!this.events[event]) this.events[event] = [];
        this.events[event].push(callback);
    }
}

I know in Production this won't happen but, it's frustrating to have this happening while I'm coding. What should I do? Get rid of StrictMode?

EDIT: This is how I'm using the EventEmitter in Home view:

import { EventEmitter } from '../../services/event-emitter';
import { Events } from '../../services/index';

class HomeView extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            items: []
        }

        EventEmitter.subscribe(Events.REMOVED_ITEM_EVENT, this.onItemRemoved);
    }

    ...
}

Thanks.

Upvotes: 0

Views: 1049

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53994

When you subscribe in the constructor, it invoked twice, try to subscribe in the component's lifecycle where it supposed to be done.

componentDidMount = () => {
  EventEmitter.subscribe(Events.REMOVED_ITEM_EVENT, this.onItemRemoved);
};

You even have such anti-pattern example in the docs:

class TopLevelRoute extends React.Component {
  constructor(props) {
    super(props);

    SharedApplicationState.recordEvent('ExampleComponent');
  }
}

At first glance, this code might not seem problematic. But if SharedApplicationState.recordEvent is not idempotent, then instantiating this component multiple times could lead to an invalid application state. This sort of subtle bug might not manifest during development, or it might do so inconsistently and so be overlooked.

Upvotes: 2

Related Questions