Today we will make a take a very swift walktrough of the ReasonReact codebase. Our objective is understanding how to use a component and how it is implemented.

Unfortunately the difference between the websites for ReasonML and ReasonReact is not only the colour but the API description. On the ReasonReact there is none.

We are gonna take a look at the React module available in ReactMini

componentSpec(_, stateless, _) a record type containing fields that are used by the React runtime

  • debugName
  • willReceiveProps
  • didMount
  • didUpdate
  • willUnmount
  • willUpdate
  • shouldUpdate
  • render
  • initialState
  • reducer
  • printState
  • handedOffInstance
  • key

the interesting bits are render : (_self) => assert false, initialState : () => (), reducer : (_action, _state) => NoUpdate and are the one you should implement in your component

what is printState?

let basicComponent = (~useDynamicKey=false, debugName) : componentSpec(_, stateless, _) => {
  let key = useDynamicKey ? Key.first : Key.none;
  {
    debugName,
    willReceiveProps: ({state}) => state,
    didMount: defaultDidMount,
    didUpdate: defaultDidUpdate,
    willUnmount: (_self) => (),
    willUpdate: defaultWillUpdate,
    shouldUpdate: defaultShouldUpdate,
    render: (_self) => assert false,
    initialState: () => (),
    reducer: (_action, _state) => NoUpdate,
    printState: (_state) => "",
    handedOffInstance: ref(None),
    key
  }
};
let statelessComponent = (~useDynamicKey=?, debugName) => {
  ...basicComponent(~useDynamicKey?, debugName),
  initialState: () => ()
};

let statefulComponent = (~useDynamicKey=?, debugName) =>
  basicComponent(~useDynamicKey?, debugName);

let reducerComponent = (~useDynamicKey=?, debugName) => basicComponent(~useDynamicKey?, debugName);

So what happens when we write a component?

// this will return a `basicComponent` type with the debug name set
// to "Hello"
let component = ReasonReact.reducerComponent("Hello");

let make =  _children => {
  ...component, // this spread the component instance, every field
  // later defined will update the one "inherited" from basicComponent
  initialState: () => None,
  reducer: action =>
}