If Om is so different, it is because the abstractions the developer has to deal with are rather different from what we are used to. And the React component lifecycle is the abstraction that is probably the hardest to understand, as well as being the abstraction that you have to deal with constantly.

By lifecycle, they mean the stages of how a given thing (a component) appears in the DOM, changes and perhaps disappears from the DOM. Every framework tries to take care of certain aspects of the task at hand so that we don’t have to think about them anymore. A big part of what Om does as a framework is moving your data through these different states.

Understanding what is happening here is therefore crucial, but difficult, especially if you, like me, don’t have any direct experience with React. And of course part of the point of using a library like Om is to not have to know React that well to get going.

So here is the complete lifecycle:

IInitState

IWillMount

IDidMount

IShouldUpdate

IWillReceiveProps

IWillUpdate

IDidUpdate

IRender

IRenderState

IDisplayName

IWillUnmount

These protocols are implemented by functions in Om components. A component must implement one of the rendering protocols, the rest are optional.

This list makes things look complicated, but we can actually pare this list down considerably. For example IRender and IRenderState are conceptually identical; IShouldUpdate is something that Om takes care of by itself, but could be an issue in pure React; IDisplayName exists really for debugging only.

With a little simplification, we really have four or five concepts to worry about. The basic lifecycle starts with an initial state, ie. IIinitState . When our component comes to life, it first needs to be mounted into the DOM. Hence: IWillMount , IDidMount and IWillUnmount , when the component is finally destroyed.

Rendering is the heart of this process, at least from the programmer’s point of view, because that is where we build the HTML that the user will eventually see. An important difference with other frameworks is that rendering happens a lot. For an animation, like moving a <div> from left to right, the IRenderState function might be called several times a second. Sometimes it is better to think of your app like a movie (a cartoon, I guess) rather than a static set of objects sitting around waiting for events to happen. And if you are thinking: “that must be horribly slow”…​ well, it isn’t, thanks to React’s virtual DOM that efficiently projects changes out into the real DOM.

So, back to the lifecycle, IRenderState basically gets called whenever something changes. Besides mounting and unmounting a component, there are also the “change” phases: IShouldUpdate (which we ignore, because in Om the components “know” if they should update or not), IWillReceiveProps , IWillUpdate , and IDidUpdate . The will and did parts are fairly simple: do we need to pre-process that new data coming in before updating (and rendering)? After updating, is there something we need to do, like grabbing the DOM node that might have changed, to get its dimensions, for example? They work like hooks in other systems.