Skip to content

Commit 1d216a3

Browse files
author
Jenn Creighton
committed
Recheck a variable's value in commit phase
1 parent 6ab2fca commit 1d216a3

2 files changed

Lines changed: 78 additions & 0 deletions

File tree

src/react/hooks/__tests__/useReactiveVar.test.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,72 @@ describe("useReactiveVar Hook", () => {
169169
console.error = error;
170170
}).then(resolve, reject);
171171
});
172+
173+
describe("useEffect", () => {
174+
itAsync("works if updated higher in the component tree", async (resolve, reject) => {
175+
const counterVar = makeVar(0);
176+
177+
function ComponentOne() {
178+
const count = useReactiveVar(counterVar);
179+
180+
useEffect(() => {
181+
counterVar(1);
182+
}, []);
183+
184+
return (<div>{count}</div>);
185+
}
186+
187+
function ComponentTwo() {
188+
const count = useReactiveVar(counterVar);
189+
190+
return (<div>{count}</div>);
191+
}
192+
193+
const { getAllByText } = render(
194+
<>
195+
<ComponentOne />
196+
<ComponentTwo />
197+
</>
198+
);
199+
200+
await wait(() => {
201+
expect(getAllByText("1")).toHaveLength(2);
202+
});
203+
204+
resolve();
205+
});
206+
207+
itAsync("works if updated lower in the component tree", async (resolve, reject) => {
208+
const counterVar = makeVar(0);
209+
210+
function ComponentOne() {
211+
const count = useReactiveVar(counterVar);
212+
213+
return (<div>{count}</div>);
214+
}
215+
216+
function ComponentTwo() {
217+
const count = useReactiveVar(counterVar);
218+
219+
useEffect(() => {
220+
counterVar(1);
221+
}, []);
222+
223+
return (<div>{count}</div>);
224+
}
225+
226+
const { getAllByText } = render(
227+
<>
228+
<ComponentOne />
229+
<ComponentTwo />
230+
</>
231+
);
232+
233+
await wait(() => {
234+
expect(getAllByText("1")).toHaveLength(2);
235+
});
236+
237+
resolve();
238+
});
239+
});
172240
});

src/react/hooks/useReactiveVar.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,15 @@ export function useReactiveVar<T>(rv: ReactiveVar<T>): T {
1818
// const mute = rv.onNextChange(setValue);
1919
// return () => mute();
2020
// }, [value])
21+
22+
// We check the variable's value in this useEffect and schedule an update if
23+
// the value has changed. This check occurs once, on the initial render, to avoid
24+
// a useEffect higher in the component tree changing a variable's value
25+
// before the above useEffect can set the onNextChange handler. Note that React
26+
// will not schedule an update if setState is called with the same value as before.
27+
useEffect(() => {
28+
setValue(rv())
29+
}, []);
30+
2131
return value;
2232
}

0 commit comments

Comments
 (0)