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

Multiple load functions #3042

Closed
bleucitron opened this issue Dec 14, 2021 · 1 comment
Closed

Multiple load functions #3042

bleucitron opened this issue Dec 14, 2021 · 1 comment

Comments

@bleucitron
Copy link
Contributor

bleucitron commented Dec 14, 2021

Describe the problem

Say I have a load function that fetches data based on:

  • page.params.paramA
  • page.params.paramB
  • or any other page/session argument that would rerun load

Each data fetching call is independent from one another.

If I goto to change only paramA, all my data fetching calls will be rerun, when only the one depending on paramA needs to rerun.

Describe the proposed solution

I'd like to be able to define different load functions that would refetch if its dependencies change, but would return a Promise.resolve() of previously fetched data if other params change.

For instance, we might imagine a loaders field in load inputs, and other loadX functions with the same load signature:

function loadA({ page, fetch }) {
    return fetch(`/some-endpoint/${page.param.a}`);
}

function loadB({ page, fetch }) {
    return fetch(`/some-endpoint/${page.param.b}`);
}

export function load({ loaders }) {
    return Promise.all(loaders).then(([dataA, dataB]) => {
        return {};
    });
}

Alternatives considered

Use data fetching without load, with onMount.

Importance

nice to have

Additional Information

No response

@Rich-Harris
Copy link
Member

This would make the API around data fetching quite a bit more complicated. This is something that's probably better implemented in userland:

const cache = new Map();

function cached(id, fn) {
  if (!cache.has(id)) {
    cache.set(id, fn());
  }

  return cache.get(id);
}

export async function load({ fetch, params }) {
  const [a, b] = Promise.all([
    cached(params.a, () => fetch(`/some-endpoint/${params.a}`).then(r => r.json()),
    cached(params.b, () => fetch(`/some-endpoint/${params.b}`).then(r => r.json()),
  ]);

  return {
    props: { a, b }
  };
}

You'd obviously have to consider when to invalidate the cache; this could be done using lifecycle functions in the component if you didn't want the cache to survive indefinitely.

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

2 participants