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

Allow fragments to be read without a hook #273

Open
rbalicki2 opened this issue Nov 14, 2024 · 0 comments
Open

Allow fragments to be read without a hook #273

rbalicki2 opened this issue Nov 14, 2024 · 0 comments

Comments

@rbalicki2
Copy link
Collaborator

rbalicki2 commented Nov 14, 2024

fragmentReference.read() would be so nice! You can do it conditionally! You can do it in a loop! Rules of hooks are annoying!

But how? Reading a fragment reference creates subscriptions in useEffect. Alas, we are foiled. It cannot be done. We must give up

Sketch of solution

But wait! We have a secret weapon, the fact that we can do whatever we want in componentCache. A sketch of a solution might look like:

  • in the component cache, we call the inner function:
return readerWithRefetchQueries.readerArtifact.resolver(
  {
    data,
    parameters: fragmentReference.variables,
  },
  additionalRuntimeProps,
);

As part of parameter one, we can pass a read function, which:

  • reads the fragment reference (this can be done imperatively with no problem), and
  • registers the fact that this fragment was read. Then, after we call the resolver, we can call useEffect, e.g.:
const fragmentsRead = [];
function read(fragment) {
  fragmentsRead.push(fragment);
  return readFragmentData(fragment);
}

const jsxResult = readerWithRefetchQueries.readerArtifact.resolver(
  {
    data,
    parameters: fragmentReference.variables,
    read,
  },
  additionalRuntimeProps,
);
useEffect(() => {
  // subscribe to each fragment read
});

return jsxResult;

Wowzers! We did it! We defeated the fish-grabbin' rules of hooks.

Alternative solution:

  • Alternatively, read can be imported, or a fragment has a .read method (I am partial to this), and calling read/.read pushes the fragment onto an array held in some context.
  • This context is provided in a component that specifically wraps the component we created in componentCache, e.g.:
function Wrapper(props) {
  return <ProvideContext><Component {...props} /></ProvideContext>
}
return Wrapper;
  • We can probably add some checks to ensure that read is only called during the render of a component with this context.
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

No branches or pull requests

1 participant