Skip to content
This repository has been archived by the owner on Feb 24, 2020. It is now read-only.

[WIP] BUG: 'Long-lived' setState function fails to persist updates #44

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion lib/Reactify.re
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ module Make = (ReconcilerImpl: Reconciler) => {
};

module State = State;
module Effects = Effects;
module Event = Event;
module Utility = Utility;
module Object = Object;
module Object = Object;
1 change: 1 addition & 0 deletions lib/Reactify.rei
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
48 changes: 42 additions & 6 deletions test/HooksUseStateTest.re
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
});

<aComponent testVal=s />;
<aComponent testVal=s/>;
},
~children,
)
Expand Down Expand Up @@ -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();
});
Expand All @@ -176,7 +178,7 @@ test("useState", () => {
)
);

test("nested state works as expected", () => {
test("nested state works", () => {
let rootNode = createRootNode();
let container = createContainer(rootNode);

Expand Down Expand Up @@ -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,
<ComponentThatUpdatesStateAndRendersChildren event=outerEvent>
<ComponentThatUpdatesState condition=Effects.MountUnmount event=innerEvent />
</ComponentThatUpdatesStateAndRendersChildren>,
);

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(
Expand Down
28 changes: 0 additions & 28 deletions test/StateTest.ts

This file was deleted.