Skip to content

Commit

Permalink
Merge pull request #7652 from apollographql/7609-useReactiveVar-regre…
Browse files Browse the repository at this point in the history
…ssion

Recheck reactive variable's value in commit phase
  • Loading branch information
jcreighton authored Feb 4, 2021
2 parents 6ab2fca + d976978 commit 541d333
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## Apollo Client 3.3.8

### Bug Fixes

- Catch updates in `useReactiveVar` with an additional check. <br/>
[@jcreighton](https://github.com/jcreighton) in [#7652](https://github.com/apollographql/apollo-client/pull/7652)

## Apollo Client 3.3.7

### Bug Fixes
Expand Down
68 changes: 68 additions & 0 deletions src/react/hooks/__tests__/useReactiveVar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,72 @@ describe("useReactiveVar Hook", () => {
console.error = error;
}).then(resolve, reject);
});

describe("useEffect", () => {
itAsync("works if updated higher in the component tree", async (resolve, reject) => {
const counterVar = makeVar(0);

function ComponentOne() {
const count = useReactiveVar(counterVar);

useEffect(() => {
counterVar(1);
}, []);

return (<div>{count}</div>);
}

function ComponentTwo() {
const count = useReactiveVar(counterVar);

return (<div>{count}</div>);
}

const { getAllByText } = render(
<>
<ComponentOne />
<ComponentTwo />
</>
);

await wait(() => {
expect(getAllByText("1")).toHaveLength(2);
});

resolve();
});

itAsync("works if updated lower in the component tree", async (resolve, reject) => {
const counterVar = makeVar(0);

function ComponentOne() {
const count = useReactiveVar(counterVar);

return (<div>{count}</div>);
}

function ComponentTwo() {
const count = useReactiveVar(counterVar);

useEffect(() => {
counterVar(1);
}, []);

return (<div>{count}</div>);
}

const { getAllByText } = render(
<>
<ComponentOne />
<ComponentTwo />
</>
);

await wait(() => {
expect(getAllByText("1")).toHaveLength(2);
});

resolve();
});
});
});
10 changes: 10 additions & 0 deletions src/react/hooks/useReactiveVar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,15 @@ export function useReactiveVar<T>(rv: ReactiveVar<T>): T {
// const mute = rv.onNextChange(setValue);
// return () => mute();
// }, [value])

// We check the variable's value in this useEffect and schedule an update if
// the value has changed. This check occurs once, on the initial render, to avoid
// a useEffect higher in the component tree changing a variable's value
// before the above useEffect can set the onNextChange handler. Note that React
// will not schedule an update if setState is called with the same value as before.
useEffect(() => {
setValue(rv())
}, []);

return value;
}

0 comments on commit 541d333

Please sign in to comment.