Skip to content
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

Add useQueryNormalizer #2

Merged
merged 6 commits into from
Jul 22, 2023
Merged

Add useQueryNormalizer #2

merged 6 commits into from
Jul 22, 2023

Conversation

klis87
Copy link
Owner

@klis87 klis87 commented Jun 24, 2023

No description provided.

Comment on lines 11 to 15
const [queryNormalizer] = useState(() =>
createQueryNormalizer(queryClient, normalizerConfig),
);

useEffect(() => () => queryNormalizer.clear(), []);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're still subscribing to the QueryCache in createQueryNormalizer, which happens synchronously during render. I was thinking that this hook should:

  • create a queryNormalizer in state
  • have an effect that calls subscribe, which returns an unsubscribe function:
  const [queryNormalizer] = useState(() =>
    createQueryNormalizer(queryClient, normalizerConfig),
  );

  useEffect(() => queryNormalizer.subscribe(), [queryNormalizer]);

I'm also not sure why unsubscribe is combined with calling clearNormalizedData(). Do we have to clear everything only because we unsubscribe ?

Copy link
Owner Author

@klis87 klis87 Jun 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're still subscribing to the QueryCache in

createQueryNormalizer does not have subscribe method actually, it works like typical class, when you create an instance which subscribes to necessary events during its creation. Do you think about some cases for which it would be better to have dedicated subscribe method?

EDIT: ahh, you are worried it is done in render function, do you think it matters? it is done only once anyway during state creation, could it cause any issues?

I'm also not sure why unsubscribe is combined with calling clearNormalizedData(). Do we have to clear everything only because we unsubscribe ?

For simplicity, I think there is no case in which you would like to clear all data without unsubscribing, or vice versa. See https://github.com/klis87/normy/blob/master/packages/normy-react-query/src/index.ts#L100 Generally this method is only for a case where for some reason you want to put queryClient to garbage collection. Then it makes sense to do the same for normalized store. But until queryClient exists, there is no sense to do any of those 2, because then you will lose synchronization between normalized store and queryClient

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it works like typical class, when you create an instance which subscribes to necessary events during its creation.

Again, I'd split that up. The constructor shouldn't subscribe, as this (potentially) won't work well in react. We do the same thing with our QueryObserver. The constructor creates an instance:

but you need to invoke .subscribe separately (in a useEffect or useSyncExternalStore call):

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points, especially with concurrent React, it is better to play safe. I separated both subscribe and unsubscribe in 6629125

Anyway, probably this will PR will be refactored. Probably current version of useQueryNormalizer will become QueryNormalizerProvider, and I will add new useQueryNormalizer which will get just queryNormalizer instance from context. This will be useful for queryNormalizer.setNormalizedData suggestion - #4 (comment) , so that we could update normalized data from an external source, be it websocket. Very handy for example here - https://tkdodo.eu/blog/using-web-sockets-with-react-query#partial-data-updates , instead of calling setQueriesData, you could just put data to setNormalizedData and all dependent queries for a given object/objects would be automatically updated, like after a mutation.

@klis87 klis87 merged commit a231ee3 into master Jul 22, 2023
@klis87 klis87 deleted the react-hooks branch November 13, 2023 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants