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?
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!