Patrick Desjardins Blog
Patrick Desjardins picture from a conference

React Autobinding and how to force component to re-attach its events

Posted on: 2016-09-26

This is not a usual scenario but imagine that you have a component that must reattach its events. How would you do it? The use case is that when a user click a link from the menu that we create the top level component which attach event to a store, etc. We want to attach everytime to a new store, thus not having any listener to the old one. The reason is that it's a cheap way to reset the JavaScript store and be sure to have no old events listening to the new view. However, if you just use React.createElement() you will endup that any subsequent creation will not trigger componentDidMount. That cause the component not listening to the store.

Under the hood, React knows to handle binding events, even if it doesn't hit again the mounting method. It's called Event Delegation and AutoBinding. The event delegation is that every event attached are attached at the top level component instead of sub-component. React dispatches the event to the proper component when an action occurs. The AutoBinding part is if you create a new object and this one is the same type and the same hiearchy level, this one doesn't need to re-attach events -- React already knows about it and it will handle the delegation properly to the new component. That is the reason that if you create a component and create it again that this one will not call componentDidMount but it will still have the listener to the store.

The problem is that if you want to reset those listeners, how do you do? How can you force the AutoBinding to reset all listeners? The solution is with key. The binding is associated to a component by this identifier. If you do not provide one, React is smart enough to figure out that you are creating again the same component and do some optimization like AutoBinding. If you want to skip this optimization and create from scratch, you need to setup a unique key. If you are clicking on different view, you can use the view id as the component key. If you want to have always a new creation, you can use a GUID.

 React.createElement(MyComponent, { props1: "value1", key: newGuid() } );