Docs / ReasonReact / Lifecycles


The Record API is in feature-freeze. For the newest features and better support going forward, please consider migrating to the new function components.

ReasonReact supports the familiar ReactJS lifecycle events.

didMount: self => unit willReceiveProps: self => state shouldUpdate: oldAndNewSelf => bool willUpdate: oldAndNewSelf => unit didUpdate: oldAndNewSelf => unit willUnmount: self => unit


  • We've dropped the component prefix from all these.

  • willReceiveProps asks for the return type to be state, not update state (i.e. not NoUpdate/Update/SideEffects/UpdateWithSideEffects). We presume you'd always want to update the state in this lifecycle. If not, simply return the previous state exposed in the lifecycle argument.

  • didUpdate, willUnmount and willUpdate don't allow you to return a new state to be updated, to prevent infinite loops.

  • willMount is unsupported. Use didMount instead.

  • didUpdate, willUpdate and shouldUpdate take in a oldAndNewSelf record, of type {oldSelf: self, newSelf: self}. These two fields are the equivalent of ReactJS' componentDidUpdate's prevProps/prevState/ in conjunction with props/state. Likewise for willUpdate and shouldUpdate.

If you need to update state in a lifecycle event, simply send an action to reducer and handle it correspondingly: self.send(DidMountUpdate).

Some new lifecycle methods act differently. Described below.

Access next or previous props: retainedProps

One pattern that's sometimes used in ReactJS is accessing a lifecycle event's prevProps (componentDidUpdate), nextProps (componentWillUpdate), and so on. ReasonReact doesn't automatically keep copies of previous props for you. We provide the retainedProps API for this purpose:

type retainedProps = {message: string}; let component = ReasonReact.statelessComponentWithRetainedProps("RetainedPropsExample"); let make = (~message, _children) => { ...component, retainedProps: {message: message}, didUpdate: ({oldSelf, newSelf}) => if (oldSelf.retainedProps.message !== newSelf.retainedProps.message) { /* do whatever sneaky imperative things here */ Js.log("props `message` changed!") }, render: (_self) => /* ... */ };

We expose ReasonReact.statelessComponentWithRetainedProps and ReasonReact.reducerComponentWithRetainedProps. Both work like their ordinary non-retained-props counterpart, and require you to specify a new field, retainedProps (of whatever type you'd like) in your component's spec in make.


Traditional ReactJS componentWillReceiveProps takes in a nextProps. We don't have nextProps, since those are simply the labeled arguments in make, available to you in the scope. To access the current props, however, you'd use the above retainedProps API:

type state = {someToggle: bool}; let component = ReasonReact.reducerComponentWithRetainedProps("MyComponent"); let make = (~name, _children) => { ...component, initialState: () => {someToggle: false}, /* just like state, the retainedProps field can return anything! Here it retained the `name` prop's value */ retainedProps: name, willReceiveProps: (self) => { if (self.retainedProps === name) { /* ... */ /* previous ReactJS logic would be: if ( === */ }; /* ... */ } };


ReactJS' componentWillUpdate's nextProps is just the labeled arguments in make, and "current props" (aka this.props) is the props you've copied into retainedProps, accessible via {oldSelf}:

{ ...component, willUpdate: ({oldSelf, newSelf}) => /* ... */ }


ReactJS' prevProps is what you've synced in retainedProps, under oldSelf.


ReactJS' shouldComponentUpdate counterpart.