-
-
Save bloodyowl/3b9e17efb829911080b231f93d6cbb0f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DeeperCounter = { | |
let make = (~initialValue, _) => { | |
let (value, setValue) = React.useState(initialValue); | |
<input | |
value | |
onChange={event => setValue(event->ReactEvent.Form.target##value)} | |
/>; | |
}; | |
}; | |
module Counter = { | |
let make = (~initialValue, _) => { | |
let (value, setValue) = React.useState(initialValue); | |
let (childrenCount, setChildrenCount) = React.useState(0); | |
<div> | |
<div> | |
<input | |
value | |
onChange={event => setValue(event->ReactEvent.Form.target##value)} | |
/> | |
</div> | |
<div> | |
<button onClick={_ => setChildrenCount(childrenCount + 1)}> | |
"Add an input with first value as default"->ReasonReact.string | |
</button> | |
</div> | |
<div> | |
{ | |
Belt.Array.make(childrenCount, ()) | |
->Belt.Array.mapWithIndex((index, ()) => | |
<div key={j|$index|j}> | |
{ | |
React.createElement( | |
DeeperCounter.make, | |
DeeperCounter.make(~initialValue=value), | |
[||], | |
) | |
} | |
</div> | |
) | |
->ReasonReact.array | |
} | |
</div> | |
</div>; | |
}; | |
}; | |
React.Dom.renderToElementWithId( | |
React.createElement(Counter.make, Counter.make(~initialValue=""), [||]), | |
"index1", | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type element = ReasonReact.reactElement; | |
[@bs.module "react"] | |
external _useState: 'a => ('a, (. 'a) => unit) = "useState"; | |
let useState = a => { | |
let (value, setValue) = _useState(a); | |
(value, newValue => setValue(. newValue)); | |
}; | |
[@bs.module "react"] | |
external _createElement: ('component, 'props, array('element)) => element = | |
"createElement"; | |
module Id = | |
Belt.Id.MakeComparable({ | |
type t = string; | |
let cmp: (string, string) => int = [%bs.raw | |
(a, b) => "return b === a ? 0 : b > a ? -1 : 1" | |
]; | |
}); | |
let components: | |
Belt.MutableMap.t( | |
string, | |
( | |
{ | |
. | |
"reasonProps": [@bs.meth] (array(element) => element), | |
"key": option(string), | |
}, | |
array(element) | |
) => | |
element, | |
Id.identity, | |
) = | |
Belt.MutableMap.make(~id=(module Id)); | |
let createElement = (~key=?, componentMake, props, children) => { | |
let func = | |
switch (components->Belt.MutableMap.get(componentMake->Obj.magic)) { | |
| Some(func) => func | |
| None => | |
let func = (props, children) => props##reasonProps(children); | |
components->Belt.MutableMap.set(componentMake->Obj.magic, func); | |
func; | |
}; | |
_createElement(func, {"reasonProps": props, "key": key}, children); | |
}; | |
module Dom = { | |
[@bs.module "react-dom"] | |
external _render: (element, Dom.element) => element = "render"; | |
[@bs.val] [@bs.return nullable] | |
external _getElementById: string => option(Dom.element) = | |
"document.getElementById"; | |
let renderToElementWithId = (element, id) => | |
id | |
->_getElementById | |
->Belt.Option.map(domElement => _render(element, domElement)); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment