I know this is probably going to be met with what?? It’s not even released in React yet. However, I’m excited about how much this will simplify the interop. Maybe router could become just a premade hook? Maybe reducer as well? I just wanted to talk about the prospects of it.
Hooks coming to Reason React?
Not only are hooks great, they seem a great match to the functional languages, so I do hope they land soon.
I think they’re awesome, but it’s funny they’re very side-effect oriented, however they do provide a nice API, much better than classes.
With Let_anything and bs-epitath (see also) we can have an API as beautiful as with hooks (while keeping the renderprops)
Example:
let component = ReasonReact.statelessComponent("MyComp");
let make = _children => {
...component,
render: (_) => {
let%Epitath data = render => <DataConsumer render />;
let%Epitath locale = render => <LocaleSelector render />;
let%Epitath (name, setName) = render => <StringState defaultValue="maarekj" render />;
<div> /* use data, locale, name and setName */</div>
}
};
or even
let component = ReasonReact.statelessComponent("MyComp");
let make = _children => {
...component,
render: (_) => {
let%Epitath data = withDataConsumer;
let%Epitath locale = withLocale;
let%Epitath (name, setName) = withStringState(~defaultValue="maarekj");
<div> /* use data, locale, name and setName */ </div>
}
};
Example with WithState
module type Config = {type t;};
module WithStateComp = (Config: Config) => {
type state = Config.t;
type action =
| ChangeValue(state);
let component = ReasonReact.reducerComponent("StateComp");
let make = (~render, ~defaultValue: state, _) => {
...component,
initialState: () => defaultValue,
reducer: (action: action, state: state) =>
switch (action) {
| ChangeValue(value) => Update(value)
},
render: self =>
render((self.state, value => self.send(ChangeValue(value)))),
};
let withState = (~defaultValue, render) =>
ReasonReact.element(make(~defaultValue, ~render, [||]));
};
module StringState =
WithStateComp({
type t = string;
});
module IntState =
WithStateComp({
type t = int;
});
module Greeting = {
let component = ReasonReact.statelessComponent("Greeting");
let make = _children => {
...component,
render: _ => {
let%Epitath (value, setValue) = IntState.withState(~defaultValue=0);
<button onClick={_ => setValue(value + 1)}>
{ReasonReact.string(string_of_int(value))}
</button>
}
};
};
ReactDOMRe.renderToElementWithId(<Greeting />, "preview");
1 disadvantage of this method I can think of is the tree depth, your API can looks just like hooks adds more levels to your tree with each render props. Performance aside, this makes debugging with react dev tool extremely difficult
Awesome use of Let_anything
! Not a bad solution till React Hooks comes out officially.
React hooks in ReasonML now that is has been published
Feel free to try out BsReact (https://github.com/eldh/bs-react/). It supports hooks and context. (And it has a router hook )
Yes, but it doesn’t really make sense to add that without also adding support for code-splitting and React.lazy
, which is a slightly bigger task.