A higher order component is basically a reusable component which allows you to takes in another component and return a new component.
To recap about higher component check our my older post here
In ReasoML higher order function are called “Functors” which takes in a module type and returns a module type, functors are written like function, except you use module instead of const/let/var…
lets try to write a simple functor here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
module type PersonType = { type t; let fullName: (t, t) => string; }; module MakeName = (T: PersonType) => { type name = T.t; let sayName = (x, y) => "Hello I am " ++ T.fullName(x, y); }; module NameString = { type t = string; let fullName = (x, y) => x ++ y; }; module Max = MakeName(NameString) Js.log(Max.sayName("max", "li")); |
You can read read more about Functor here
So now we want to use this approach on higher order component, kind of like react, wrap component in a function, here wrap in a functor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
module type S = { type t; let equal: (t, t) => bool; }; module SelectHoc = (T:S) => { type t = { label: string, value: T.t }; let component = ReasonReact.statelessComponent("selectComponent"); let make = ( ~items: array(t), ~selectedItem, _children ) => { ...component, render: (_self) => { <select> {items->Array.map(item => <option className={ T.equals(item.value, selectedItem) ? "active" : "" } > item.label->ReasonReact.string </option> )} </select> } } }; module SelectInt = SelectHoc({ type t = string; let equals = (x, y) => x == y; }); /* use the component like this... */ let items = [| {Int.label: "first", value: 1}, {label: "second", value: 2}, {label: "third", value: 3}, {label: "fourth", value: 4}, |]; <SelectInt items selectedItem=1 /> |