Skip to content

Instantly share code, notes, and snippets.

@bloodyowl
Last active October 29, 2018 20:30
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bloodyowl/3b9e17efb829911080b231f93d6cbb0f to your computer and use it in GitHub Desktop.
Save bloodyowl/3b9e17efb829911080b231f93d6cbb0f to your computer and use it in GitHub Desktop.
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",
);
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