Skip to content

Commit

Permalink
fix stale props being passed to promiseFn when using watchFn (#181)
Browse files Browse the repository at this point in the history
fix stale props being passed to promiseFn when using watchFn
  • Loading branch information
ghengeveld authored Nov 11, 2019
2 parents 6bf5211 + dffd39f commit 2538607
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
30 changes: 27 additions & 3 deletions packages/react-async/src/specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export const withPromiseFn = (Async, abortCtrl) => () => {
expect(abortCtrl.abort).toHaveBeenCalledTimes(1)
})

test("re-runs the promise when the value of `watch` changes", () => {
test("re-runs the promise with new props when the value of `watch` changes", () => {
class Counter extends React.Component {
constructor(props) {
super(props)
Expand All @@ -304,19 +304,31 @@ export const withPromiseFn = (Async, abortCtrl) => () => {
}
const promiseFn = jest.fn().mockReturnValue(resolveTo())
const { getByText } = render(
<Counter>{count => <Async promiseFn={promiseFn} watch={count} />}</Counter>
<Counter>{count => <Async promiseFn={promiseFn} watch={count} count={count} />}</Counter>
)
expect(promiseFn).toHaveBeenCalledTimes(1)
expect(promiseFn).toHaveBeenLastCalledWith(
expect.objectContaining({ count: 0 }),
expect.any(Object)
)
fireEvent.click(getByText("increment"))
expect(promiseFn).toHaveBeenCalledTimes(2)
expect(promiseFn).toHaveBeenLastCalledWith(
expect.objectContaining({ count: 1 }),
expect.any(Object)
)
expect(abortCtrl.abort).toHaveBeenCalled()
abortCtrl.abort.mockClear()
fireEvent.click(getByText("increment"))
expect(promiseFn).toHaveBeenCalledTimes(3)
expect(promiseFn).toHaveBeenLastCalledWith(
expect.objectContaining({ count: 2 }),
expect.any(Object)
)
expect(abortCtrl.abort).toHaveBeenCalled()
})

test("re-runs the promise when `watchFn` returns truthy", () => {
test("re-runs the promise with new props when `watchFn` returns truthy", () => {
class Counter extends React.Component {
constructor(props) {
super(props)
Expand All @@ -338,11 +350,23 @@ export const withPromiseFn = (Async, abortCtrl) => () => {
<Counter>{count => <Async promiseFn={promiseFn} watchFn={watchFn} count={count} />}</Counter>
)
expect(promiseFn).toHaveBeenCalledTimes(1)
expect(promiseFn).toHaveBeenLastCalledWith(
expect.objectContaining({ count: 0 }),
expect.any(Object)
)
fireEvent.click(getByText("increment"))
expect(promiseFn).toHaveBeenCalledTimes(1)
expect(promiseFn).toHaveBeenLastCalledWith(
expect.objectContaining({ count: 0 }),
expect.any(Object)
)
expect(abortCtrl.abort).not.toHaveBeenCalled()
fireEvent.click(getByText("increment"))
expect(promiseFn).toHaveBeenCalledTimes(2)
expect(promiseFn).toHaveBeenLastCalledWith(
expect.objectContaining({ count: 2 }),
expect.any(Object)
)
expect(abortCtrl.abort).toHaveBeenCalled()
})

Expand Down
5 changes: 4 additions & 1 deletion packages/react-async/src/useAsync.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,10 @@ function useAsync<T extends {}>(
/* eslint-disable react-hooks/exhaustive-deps */
const { watch, watchFn } = options
useEffect(() => {
if (watchFn && lastOptions.current && watchFn(options, lastOptions.current)) load()
if (watchFn && lastOptions.current && watchFn(options, lastOptions.current)) {
lastOptions.current = options
load()
}
})
useEffect(() => {
lastOptions.current = options
Expand Down

0 comments on commit 2538607

Please sign in to comment.