Search code examples
reasonreason-react

`self.send` on ReasonReact Compile-time Error


Given the following:

$cat src/Greeting.re
let component = ReasonReact.reducerComponent("Greeting");

type action =
 | Click;

type state = {
    count: int
};

let make = (_children) => {
  ...component,
  initialState: () => {count: 0},
  reducer: (action, state) =>
    ReasonReact.Update({count: state.count + 1}),
  render: (self) => {
     let message = "Clicked " ++ string_of_int(self.state.count) ++ "x";
        <div>
          <button
            onClick={_event => self.send(Click)}
          />
          {ReasonReact.stringToElement(message)}
        </div>
  }
};

I get the following compile-time error:

  17 ┆ <div>
  18 ┆   <button
  19 ┆     onClick={_event => self.send(Click)}
  20 ┆   />
  21 ┆   {ReasonReact.stringToElement(message)}

  This record expression is expected to have type
    ReasonReact.componentSpec (state,  'a,  'b,  'c,  'd)
  The field send does not belong to type ReasonReact.self

ninja: build stopped: subcommand failed.
>>>> Finish compiling(exit: 1)

I don't understand. Can someone please explain what the error is and how to fix it?


Solution

  • You have to place your let component = ReasonReact.reducerComponent("Greeting"); line immediately before the make declaration, like so:

    …
    let component = ReasonReact.reducerComponent("Greeting");
    
    let make = (_children) => {
      ...component,
      initialState: () => {count: 0},
    …
    

    The reason for this is that the type of a reducer element is inferred based on other types (namely state and action) so it needs to be able to "see" them when it is declared.

    Also, for the record, you should see a warning in the bsb output about this:

    Is this a ReasonReact reducerComponent or component with retained props? If so, is the type for state, retained props or action declared after the component declaration? Moving these types above the component declaration should resolve this!

    Try to run npm run start again to see warnings!