-
-
Notifications
You must be signed in to change notification settings - Fork 461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bugfixes for useQuery #243
Changes from all commits
d3ca8ff
5ce4090
3d358f2
8c26b2d
1a6d38a
a57a557
8f65db3
0533ad2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,8 @@ export type UseQueryResponse<T> = [ | |
export const useQuery = <T = any, V = object>( | ||
args: UseQueryArgs<V> | ||
): UseQueryResponse<T> => { | ||
const unsubscribe = useRef(noop); | ||
const isMounted = useRef(true); | ||
const unsubscribe = useRef<() => void>(noop); | ||
|
||
const client = useContext(Context); | ||
const request = useMemo( | ||
|
@@ -47,36 +48,46 @@ export const useQuery = <T = any, V = object>( | |
data: undefined, | ||
}); | ||
|
||
/** Unmount handler */ | ||
useEffect( | ||
() => () => { | ||
isMounted.current = false; | ||
}, | ||
[] | ||
); | ||
|
||
const executeQuery = useCallback( | ||
(opts?: Partial<OperationContext>) => { | ||
unsubscribe.current(); | ||
|
||
setState(s => ({ ...s, fetching: true })); | ||
if (args.pause) { | ||
unsubscribe.current = noop; | ||
return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the early There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks Parker, I'll investigate tonight 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking a little more closely, it appears that the failed tests are related to the effect not re-running when new variables, query, and requestPolicy are received 🤔 Not totally sure why that would be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @parkerziegler I've managed to fix the tests by removing the waitForUpdate call. Given tests themselves are checking that a re-fetch is triggered we can get away without waiting for state updates. As for why those state updates aren't taking place in a test environment, I suspect it's related to the mock implementation of executeQuery. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha, will dig into this more tomorrow to confirm. But agree, as long as we're sure that |
||
} | ||
|
||
let teardown = noop; | ||
setState(s => ({ ...s, fetching: true })); | ||
|
||
if (!args.pause) { | ||
[teardown] = pipe( | ||
client.executeQuery(request, { | ||
requestPolicy: args.requestPolicy, | ||
...opts, | ||
}), | ||
subscribe(({ data, error }) => { | ||
setState({ fetching: false, data, error }); | ||
}) | ||
); | ||
} else { | ||
setState(s => ({ ...s, fetching: false })); | ||
} | ||
const [teardown] = pipe( | ||
client.executeQuery(request, { | ||
requestPolicy: args.requestPolicy, | ||
...opts, | ||
}), | ||
subscribe( | ||
({ data, error }) => | ||
isMounted.current && setState({ fetching: false, data, error }) | ||
) | ||
); | ||
|
||
unsubscribe.current = teardown; | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[request.key, client, args.pause, args.requestPolicy] | ||
); | ||
|
||
/** Trigger query on arg change. */ | ||
useEffect(() => { | ||
executeQuery(); | ||
|
||
return unsubscribe.current; | ||
}, [executeQuery]); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think I saw a comment in an email from you @andyrichardson, but yep, to explain the naming behind this file, I basically wanted a way to differentiate it from
useQuery.test.tsx
. I'd be happy to use a different name. Part of the reason for bringing inreact-hooks-testing-library
was to make us less dependent onenzyme
, to avoid re-assignment of let bindings in tests, and to be able to get the direct values returned by our hooks so we can assert on them (which I think has some value). Perhaps we could specify these two files asuseQuery.enzyme.test.tsx
anduseQuery.rhtl.test.tsx
? I'm also fine with removing them if we don't think they have value or we don't like the API, I just find the it a bit easier to work w/ thanenzyme
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cheers @parkerziegler - I initially asked but then found your PR with the explanation. No need to make changes 👍
I'm pretty sure
react-hooks-testing-library
is using react-test-renderer under the hood (we're not using enzyme). I agree the reassignment + added complexity is a pain 😑