-
-
Notifications
You must be signed in to change notification settings - Fork 94
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
useFetcher getter class inheritance issues #458
Comments
I believe this may actually be returning a POJO than a class. Can you verify if it can even use getters in the descendant class from useFetcher()? Changing this to return the class is planned for v5, which will also guarantee referential equality. |
You're right. Looks like a POJO, all getters are undefined. Thanks for the context Is this included in the current v5 beta version? |
Not yet. As a workaround, you could do the following for now (assumes running v5 beta): import { normalize, denormalize } from '@rest-hooks/normalizr';
import { useFetcher } from 'rest-hooks';
function useBetterFetcher<
Shape extends FetchShape<Schema, Readonly<object>, any>
>(
endpoint: Shape,
throttle = false,
) {
const fetch = useFetcher(endpoint, throttle);
return useCallback(async (...args: Parameters<fetch>) => {
const res = await fetch(...args);
const { entities, result } = normalize(res);
return denormalize(result, endpoint.schema, entities);
}, [ fetch ]);
} |
Will give that a shot, thank you! |
Open questionSay a fetch returns an entity that is already in store. In some cases (due to race conditions) you might want to (use the existing entity, because it's actually newer](https://resthooks.io/docs/next/api/SimpleRecord#static-merget-extends-typeof-simplerecordfirst-instancetypet-second-instancetypet--instancetypet) (which can be determined by a timestamp). This already affected what is returned by useResource() or useCache(). However, should it also affect the return value of a fetch? That is to say, should we
Given that imperative fetches can have side effects, it's not clear which would be better. Should we maybe then provide both? or maybe a different hook for each case? |
@ntucker I'm running into a variant of this issue as well, and my vote is for 2). My rationale is:
|
@yunyu I'm a bit confused, because you talk about denormalized version (which is what useResource() returns - includes class properties, etc). but then say #2 - which returns the raw fetch response (which won't have classes). Both can have any additional data from the fetch - just one is processed through the cache and the other is the input to that processing. |
@ntucker Sorry, I realized that I was advocating for a 3rd solution (return a denormalized version of the result from the fetch). What I meant to say is that IMO, the return value of useFetcher should represent the entity at the time when the fetch call succeeds and not subsequent updates. |
There's another context in which this behavior poses a type safety issue. If you fetch a resource with a defined |
Tracking solution in #760 |
Resolution from useFetch and ctrl.fetch() now resolves to a denormalized form (tho does not incorporate any existing entities from state). This was first introduced in rest hooks 8. Though not all schemas work perfectly until data client 0.11 |
React version
16.13.1
Concurrent mode
No
Rest Hooks version
4.5.5
Describe the bug
Getter inheritance not working as expected with useFetcher. e.g. given a class
ResourceA
and a subclassResourceB extends ResourceA
. The object returned byuseFetcher(ResourceB.someShape())
is missing getters fromResourceA
. This is not an issue with useResource.To Reproduce
Steps to reproduce the behavior:
Deletable posts is empty regardless of the value of this.active. The behavior works as expected when doing
Expected behavior
I would expect class inheritance of getters to be consistent across useResource and useFetcher. Ideally, subclasses in both cases would have access to the parent getter.
Additional context
Manually setting the object prototype via
setPrototypeOf
does not work either. Intellisense/TS has no complaints about calling the getters.ES6 context:
https://stackoverflow.com/questions/53584705/javascript-extending-es6-class-setter-will-inheriting-getter
TS context:
microsoft/TypeScript#338
microsoft/TypeScript#25927
Thanks!
The text was updated successfully, but these errors were encountered: