Skip to content

Commit 2538607

Browse files
authored
fix stale props being passed to promiseFn when using watchFn (#181)
fix stale props being passed to promiseFn when using watchFn
2 parents 6bf5211 + dffd39f commit 2538607

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

packages/react-async/src/specs.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ export const withPromiseFn = (Async, abortCtrl) => () => {
286286
expect(abortCtrl.abort).toHaveBeenCalledTimes(1)
287287
})
288288

289-
test("re-runs the promise when the value of `watch` changes", () => {
289+
test("re-runs the promise with new props when the value of `watch` changes", () => {
290290
class Counter extends React.Component {
291291
constructor(props) {
292292
super(props)
@@ -304,19 +304,31 @@ export const withPromiseFn = (Async, abortCtrl) => () => {
304304
}
305305
const promiseFn = jest.fn().mockReturnValue(resolveTo())
306306
const { getByText } = render(
307-
<Counter>{count => <Async promiseFn={promiseFn} watch={count} />}</Counter>
307+
<Counter>{count => <Async promiseFn={promiseFn} watch={count} count={count} />}</Counter>
308308
)
309309
expect(promiseFn).toHaveBeenCalledTimes(1)
310+
expect(promiseFn).toHaveBeenLastCalledWith(
311+
expect.objectContaining({ count: 0 }),
312+
expect.any(Object)
313+
)
310314
fireEvent.click(getByText("increment"))
311315
expect(promiseFn).toHaveBeenCalledTimes(2)
316+
expect(promiseFn).toHaveBeenLastCalledWith(
317+
expect.objectContaining({ count: 1 }),
318+
expect.any(Object)
319+
)
312320
expect(abortCtrl.abort).toHaveBeenCalled()
313321
abortCtrl.abort.mockClear()
314322
fireEvent.click(getByText("increment"))
315323
expect(promiseFn).toHaveBeenCalledTimes(3)
324+
expect(promiseFn).toHaveBeenLastCalledWith(
325+
expect.objectContaining({ count: 2 }),
326+
expect.any(Object)
327+
)
316328
expect(abortCtrl.abort).toHaveBeenCalled()
317329
})
318330

319-
test("re-runs the promise when `watchFn` returns truthy", () => {
331+
test("re-runs the promise with new props when `watchFn` returns truthy", () => {
320332
class Counter extends React.Component {
321333
constructor(props) {
322334
super(props)
@@ -338,11 +350,23 @@ export const withPromiseFn = (Async, abortCtrl) => () => {
338350
<Counter>{count => <Async promiseFn={promiseFn} watchFn={watchFn} count={count} />}</Counter>
339351
)
340352
expect(promiseFn).toHaveBeenCalledTimes(1)
353+
expect(promiseFn).toHaveBeenLastCalledWith(
354+
expect.objectContaining({ count: 0 }),
355+
expect.any(Object)
356+
)
341357
fireEvent.click(getByText("increment"))
342358
expect(promiseFn).toHaveBeenCalledTimes(1)
359+
expect(promiseFn).toHaveBeenLastCalledWith(
360+
expect.objectContaining({ count: 0 }),
361+
expect.any(Object)
362+
)
343363
expect(abortCtrl.abort).not.toHaveBeenCalled()
344364
fireEvent.click(getByText("increment"))
345365
expect(promiseFn).toHaveBeenCalledTimes(2)
366+
expect(promiseFn).toHaveBeenLastCalledWith(
367+
expect.objectContaining({ count: 2 }),
368+
expect.any(Object)
369+
)
346370
expect(abortCtrl.abort).toHaveBeenCalled()
347371
})
348372

packages/react-async/src/useAsync.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,10 @@ function useAsync<T extends {}>(
196196
/* eslint-disable react-hooks/exhaustive-deps */
197197
const { watch, watchFn } = options
198198
useEffect(() => {
199-
if (watchFn && lastOptions.current && watchFn(options, lastOptions.current)) load()
199+
if (watchFn && lastOptions.current && watchFn(options, lastOptions.current)) {
200+
lastOptions.current = options
201+
load()
202+
}
200203
})
201204
useEffect(() => {
202205
lastOptions.current = options

0 commit comments

Comments
 (0)