diff --git a/lib/Reactify.re b/lib/Reactify.re
index 37342f3..3feef9e 100644
--- a/lib/Reactify.re
+++ b/lib/Reactify.re
@@ -518,6 +518,7 @@ module Make = (ReconcilerImpl: Reconciler) => {
};
module State = State;
+module Effects = Effects;
module Event = Event;
module Utility = Utility;
-module Object = Object;
\ No newline at end of file
+module Object = Object;
diff --git a/lib/Reactify.rei b/lib/Reactify.rei
index e9af404..18a3329 100644
--- a/lib/Reactify.rei
+++ b/lib/Reactify.rei
@@ -7,6 +7,7 @@ module Make:
type node = ReconcilerImpl.node and
type primitives = ReconcilerImpl.primitives;
+module Effects = Effects;
module State = State;
module Event = Event;
module Utility = Utility;
diff --git a/test/HooksUseStateTest.re b/test/HooksUseStateTest.re
index 2fd154b..6b43cc9 100644
--- a/test/HooksUseStateTest.re
+++ b/test/HooksUseStateTest.re
@@ -5,6 +5,8 @@ open TestReconciler;
open TestUtility;
module Event = Reactify.Event;
+module Effects = Reactify.Effects;
+
/* Use our Reconciler to create our own instance */
module TestReact = Reactify.Make(TestReconciler);
@@ -51,19 +53,19 @@ test("useState", () => {
});
module ComponentThatUpdatesState = (
- val component((render, ~children, ~event: Event.t(int), ()) =>
+ val component((render, ~condition=Effects.Always, ~children, ~event: Event.t(int), ()) =>
render(
() => {
/* Hooks */
let (s, setS) = useState(2);
/* End hooks */
- useEffect(() => {
+ useEffect(~condition, () => {
let unsubscribe = Event.subscribe(event, v => setS(v));
() => unsubscribe();
});
- ;
+ ;
},
~children,
)
@@ -157,13 +159,13 @@ test("useState", () => {
});
module ComponentThatUpdatesStateAndRendersChildren = (
- val component((render, ~children, ~event: Event.t(int), ()) =>
+ val component((render, ~condition=Effects.Always, ~children, ~event: Event.t(int), ()) =>
render(
() => {
/* Hooks */
let (s, setS) = useState(2);
- useEffect(() => {
+ useEffect(~condition, () => {
let unsubscribe = Event.subscribe(event, v => setS(v));
() => unsubscribe();
});
@@ -176,7 +178,7 @@ test("useState", () => {
)
);
- test("nested state works as expected", () => {
+ test("nested state works", () => {
let rootNode = createRootNode();
let container = createContainer(rootNode);
@@ -210,6 +212,40 @@ test("useState", () => {
validateStructure(rootNode, expectedStructure);
});
+ test("regression test: nested state w/ long-lived handle to setState", () => {
+ let rootNode = createRootNode();
+ let container = createContainer(rootNode);
+
+ let outerEvent = Event.create();
+ let innerEvent = Event.create();
+
+ updateContainer(
+ container,
+
+
+ ,
+ );
+
+ let expectedStructure: tree(primitives) =
+ TreeNode(Root, [TreeNode(A(2), [TreeLeaf(A(2))])]);
+ validateStructure(rootNode, expectedStructure);
+
+ Event.dispatch(outerEvent, 5);
+ let expectedStructure: tree(primitives) =
+ TreeNode(Root, [TreeNode(A(5), [TreeLeaf(A(2))])]);
+ validateStructure(rootNode, expectedStructure);
+
+ Event.dispatch(innerEvent, 6);
+ let expectedStructure: tree(primitives) =
+ TreeNode(Root, [TreeNode(A(5), [TreeLeaf(A(6))])]);
+ validateStructure(rootNode, expectedStructure);
+
+ Event.dispatch(outerEvent, 7);
+ let expectedStructure: tree(primitives) =
+ TreeNode(Root, [TreeNode(A(7), [TreeLeaf(A(6))])]);
+ validateStructure(rootNode, expectedStructure);
+ });
+
module ComponentThatWrapsEitherPrimitiveOrComponent = (
val component((render, ~children, ~event: Event.t(renderOption), ()) =>
render(
diff --git a/test/StateTest.ts b/test/StateTest.ts
deleted file mode 100644
index eb93dca..0000000
--- a/test/StateTest.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-module State = Reactify.State;
-
-test("Object conversion works with ints", () => {
- let i = 1;
- let stateI = Object.to_object(i);
- let rehydratedI = Object.of_object(stateI);
- assert(i == rehydratedI);
-});
-
-test("Object conversion works with tuples", () => {
- let p = (1, "a");
- let stateP = Object.to_object(p);
- let rehydratedP = Object.of_object(stateP);
- assert(p == rehydratedP);
-});
-
-test("Object can be used to create list of different types", () => {
- let stateList: list(State.t) = [];
-
- let stateList = [Object.to_object(1), ...stateList];
- let stateList = [Object.to_object(("a", "b")), ...stateList];
-
- let firstElement = List.nth(stateList, 0);
- assert(Object.of_object(firstElement) == ("a", "b"));
-
- let lastElement = List.nth(stateList, 1);
- assert(Object.of_object(lastElement) == 1);
-});