Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ref might contain a cleanup function #866

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
35d588c
Install melange-testing-library
davesnx Nov 18, 2024
1cd6a6b
Install melange-testing-library npm deps
davesnx Nov 18, 2024
05aa7e1
Vendor melange-testing-library
davesnx Nov 18, 2024
4434bfd
Fix Form__test with RTL
davesnx Nov 18, 2024
ab43c4b
Start migrating Hooks__test
davesnx Nov 19, 2024
8234b69
Remove dependency
davesnx Nov 19, 2024
49b35e9
Remove unused code from Form__test
davesnx Nov 19, 2024
3ca3ba1
Add a jest-devtoolsgs
davesnx Nov 19, 2024
41ba9c2
Add a jest-devtools
davesnx Nov 19, 2024
c7998a9
Migrate Hooks and Form into RTL
davesnx Nov 19, 2024
5e05f2e
Add demo to manually test easily
davesnx Nov 19, 2024
f8a08c3
Use Uncurried for tests
davesnx Nov 19, 2024
8d156d7
Migrate all React__test
davesnx Nov 19, 2024
33ad56a
Force install since we are dealing with R19
davesnx Nov 19, 2024
30d82df
Snapshot with lower {}
davesnx Nov 19, 2024
507b0fb
Enable ref in ppx
davesnx Nov 20, 2024
f3dc9f3
Add jest test for ref
davesnx Nov 20, 2024
80e85ae
Remove jest from demo/dune
davesnx Nov 20, 2024
b39168f
Add comment on install --force
davesnx Nov 20, 2024
0470e59
Improve test from checking ref
davesnx Nov 20, 2024
7aaef3e
Merge branch '19' of github.com:/reasonml/reason-react into replace-t…
davesnx Nov 25, 2024
5171ac5
Bind React.act and React.actAsync
davesnx Nov 25, 2024
ad36fbb
Bind React.act and React.actAsync
davesnx Nov 25, 2024
52addbc
Merge branch 'replace-testing-libraries' of github.com:/reasonml/reas…
davesnx Nov 25, 2024
11649de
Merge branch 'replace-testing-libraries' of github.com:/reasonml/reas…
davesnx Nov 25, 2024
2f5ae8d
Use React.act as async version only
davesnx Nov 25, 2024
44faccc
Test react.act and react.actasync
davesnx Nov 25, 2024
d168359
Fix hola test :(
davesnx Nov 25, 2024
7124732
Merge branch 'replace-testing-libraries' of github.com:/reasonml/reas…
davesnx Nov 25, 2024
e12fe31
Implement ref with cleanup
davesnx Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ jest: ## Run the jest unit tests
jest-watch: ## Run the jest unit tests in watch mode
@npx jest --watch

.PHONY: jest-devtools
jest-devtools: ## Run the jest unit tests in watch mode
@echo "open Chrome and go to chrome://inspect"
@node --inspect-brk node_modules/.bin/jest --runInBand --detectOpenHandles

.PHONY: test
test: ## Run the runtests from dune (snapshot)
@$(DUNE) build @runtest
Expand All @@ -54,11 +59,22 @@ format-check: ## Checks if format is correct
.PHONY: install
install: ## Update the package dependencies when new deps are added to dune-project
@opam install . --deps-only --with-test
@npm install
# --force is needed because we are installing react@19 while other dependencies
# require react@18. It's a good workaround to bypass the npm validation error
# and test the rc versions of React
@npm install --force

.PHONY: init
create-switch: ## Create a local opam switch
@opam switch create . 5.2.0 --no-install

.PHONY: init
init: create-switch install ## Create a local opam switch, install deps

.PHONY: demo-watch
demo-watch: ## Build the demo in watch mode
@$(DUNE) build @melange-app --watch

.PHONY: demo-serve
demo-serve: ## Build the demo and serve it
npx http-server -p 8080 _build/default/demo/
9 changes: 9 additions & 0 deletions demo/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(melange.emit
(target demo)
(alias melange-app)
(module_systems
(es6 mjs))
(libraries reason-react melange.belt melange.dom)
(runtime_deps index.html)
(preprocess
(pps melange.ppx reason-react-ppx)))
42 changes: 42 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Demo reason-react</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css-1.8.1.min.css" />
<style>
body {
padding: 2rem;
}

#root {
margin-left: auto;
margin-right: auto;
width: 900px;
}
</style>
<script type="importmap">
{
"imports": {
"melange/": "./demo/node_modules/melange/",
"melange.belt/": "./demo/node_modules/melange.belt/",
"melange.js/": "./demo/node_modules/melange.js/",
"reason-react/": "./demo/node_modules/reason-react/",
"react/jsx-runtime": "https://esm.sh/[email protected]/jsx-runtime",
"react": "https://esm.sh/[email protected]",
"react-dom": "https://esm.sh/[email protected]",
"react-dom/client": "https://esm.sh/[email protected]/client"
}
}
</script>
</head>

<body>
<div id="root"></div>
</body>
<script type="module" src="./demo/demo/main.mjs"></script>

</html>
187 changes: 187 additions & 0 deletions demo/main.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
module Stateful = {
[@react.component]
let make = (~title, ~initialValue=0, ~children=React.null) => {
let (value, setValue) = React.useState(() => initialValue);
let onClick = _ => setValue(value => value + 1);

<section>
<h3> {React.string(title)} </h3>
<button key="asdf" onClick> value->React.int </button>
children
</section>;
};
};

module Reducer = {
type action =
| Increment
| Decrement;

[@react.component]
let make = (~initialValue=0) => {
let (state, send) =
React.useReducer(
(state, action) =>
switch (action) {
| Increment => state + 1
| Decrement => state - 1
},
initialValue,
);

Js.log2("Reducer state", state);

<section>
<h3> {React.string("React.useReducer")} </h3>
<main> state->React.int </main>
<button onClick={_ => send(Increment)}>
"Increment"->React.string
</button>
<button onClick={_ => send(Decrement)}>
"Decrement"->React.string
</button>
</section>;
};
};

module ReducerWithMapState = {
type action =
| Increment
| Decrement;

[@react.component]
let make = (~initialValue=0) => {
let (state, send) =
React.useReducerWithMapState(
(state, action) =>
switch (action) {
| Increment => state + 1
| Decrement => state - 1
},
initialValue,
initialValue => initialValue + 75,
);

Js.log2("ReducerWithMapState state", state);

<section>
<h3> {React.string("React.useReducerWithMapState")} </h3>
<main> state->React.int </main>
<button onClick={_ => send(Increment)}>
"Increment"->React.string
</button>
<button onClick={_ => send(Decrement)}>
"Decrement"->React.string
</button>
</section>;
};
};

module WithEffect = {
[@react.component]
let make = (~value) => {
React.useEffect1(
() => {
Js.log("useEffect");
None;
},
[|value|],
);

React.string("React.useEffect");
};
};

module RerenderOnEachClick = {
[@react.component]
let make = (~value=0, ~callback as _) => {
let (value, setValue) = React.useState(() => value);
let onClick = _ =>
if (value < 3) {
Js.log2("Clicked with:", value);
setValue(value => value + 1);
} else {
Js.log("Max value reached, not firing a rerender");
setValue(value => value);
};

<section>
<h3> {React.string("RerenderOnEachClick")} </h3>
<button onClick> <WithEffect value /> </button>
</section>;
};
};

module WithLayoutEffect = {
[@react.component]
let make = (~value=0, ~callback) => {
React.useLayoutEffect1(
() => {
callback(value);
Js.log("useLayoutEffect");
None;
},
[|value|],
);

<section> <h3> {React.string("React.useLayoutEffect")} </h3> </section>;
};
};

module WithRefAndEffect = {
[@react.component]
let make = (~callback) => {
let myRef = React.useRef(1);
React.useEffect0(() => {
myRef.current = myRef.current + 1;
callback(myRef);
None;
});

<section>
<h3> {React.string("React.useRef and useEffect")} </h3>
<main> {React.int(myRef.current)} </main>
</section>;
};
};

[@mel.module "react"]
external useReducer:
([@mel.uncurry] (('state, 'action) => 'state), 'state) =>
('state, 'action => unit) =
"useReducer";

module UseReducerNoProblemo = {
[@react.component]
let make = () => {
let reducer = (v, _) => v + 1;
let (state, send) = useReducer(reducer, 0);
Js.log("asdfasd");
<button onClick={_ => send(0)}> {React.int(state)} </button>;
};
};

module App = {
[@react.component]
let make = (~initialValue) => {
let value = 99;
let callback = _number => ();

<main>
<Stateful title="Stateful" initialValue />
<Reducer key="reducer" initialValue />
<ReducerWithMapState key="reducer-with-map-state" initialValue />
<RerenderOnEachClick key="rerender-on-each-click" value=0 callback />
<WithLayoutEffect key="layout-effect" value callback />
<WithRefAndEffect key="ref-and-effect" callback />
<UseReducerNoProblemo />
</main>;
};
};

switch (ReactDOM.querySelector("#root")) {
| Some(el) =>
let root = ReactDOM.Client.createRoot(el);
ReactDOM.Client.render(root, <App initialValue=0 />);
| None => Js.log("No root element found")
};
2 changes: 1 addition & 1 deletion dune
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(dirs src test ppx)
(dirs src test ppx demo)
Loading
Loading