fetch-suspense icon indicating copy to clipboard operation
fetch-suspense copied to clipboard

Support fetching an array of requests.

Open BruceL33t opened this issue 5 years ago • 9 comments

First of all I'd like to thank your for this awesome package.

But now for a feature request / question.

What if I have a component that needs to do multiple fetch requests before rendering? How would you extend this hook to be able to handle multiple fetch requests?

BruceL33t avatar Mar 01 '19 17:03 BruceL33t

I don't think it is currently optimized to handle multiple fetch requests simultaneously, but they should be able to dispatch sequentially by just using the hook twice.

const x = useFetch('/path/1');
const y = useFetch('/path/2');

If you are unable to dispatch the requests sequentially, let me know, and I'll re-assign this issue as a bug.

quisido avatar Mar 01 '19 18:03 quisido

I've also got some requests that I would like to run in parallel. Would be cool that if you pass in an array, it runs them in parallel.

// sequential
useFetch('url', options) 
useFetch('url', options)

// parallel
useFetch([{ url, options }, { url, options}])

Or something like that.

sorahn avatar Mar 20 '19 14:03 sorahn

It's quite possible to build || request support like @sorahn suggested.

For example, rest hooks does this by optionally accepting multiple arguments to one call. https://github.com/coinbase/rest-hooks/blob/master/docs/guides/fetch-multiple.md

Code: https://github.com/coinbase/rest-hooks/blob/master/src/react-integration/hooks/useResource.ts#L54

Feel free to use this as inspiration!

ntucker avatar Mar 24 '19 19:03 ntucker

I'm not opposed to useFetch([]) syntax. I'll add it to the backlog behind launching ReactN 2.0.

quisido avatar Mar 24 '19 23:03 quisido

Sounds great! If possible if would be awesome if you could implement it so that you do not do like Promise.all - waiting for all promises to return, but update whenever one promise in the array resolves.. or at least, make that possible with a parameter. To update per promise vs when all promises are resolved.

BruceL33t avatar Mar 26 '19 18:03 BruceL33t

@BruceL33t Maybe I am misunderstanding your question, but If this is using suspense, isn't the entire point not to advance past the suspended code until it loads so you guarantee that all data is there once it gets to the next part of the code?

// will continue to throw until all fetches are resolved
const [response1, response2] = useFetch([request1, request2])

// If this resolved with response2 finished, but not response1, then this could would break
useOtherHookWith(response1) 

sorahn avatar Mar 26 '19 23:03 sorahn

An oddity about this syntax: how do you specify parameters?

useFetch([
  './path.json',
  './path2.json',
]);

But now I want RequestInit or lifespan on the fetch requests:

useFetch([
  './path.json',
  './path2.json', {}, 60000,
]);

Does that mean it's an array of arrays?

useFetch([
  [ './path.json' ],
  [ './path2.json', {}, 60000 ],
]);

Is there more intuitive syntax? I am not digging an array of arrays, personally.

quisido avatar Apr 12 '19 16:04 quisido

Maybe an array of objects?

If you're just doing one thing, then it's useFetch(path, data, timeout), and if you want multiple requests, its useFetch([{ path, data, timeout }, { path2, data2, timeout2 }])

That being said, I don't personally mind an array of arrays. Thats how the babel plugins work if you need the extra options, so it's not a totally alien syntax.

useFetch(path, data, timeout)

useFetch([path, path])

useFetch([path, [path, data, timeout], path) 
-or-
config3 = { data, timeout }
useFetch([path, [path2, { data, timeout}], [path3, config3]]) 

You could also just require that it always take an array, that might simplify your code. So even with one it would by useFetch([path]) that way you're just always operating on the elements of an array.

something something something less conditionals = good taste

sorahn avatar Apr 12 '19 22:04 sorahn

I'm wondering if maybe it's worth just making a generic 'suspense promise.all' component, so you could pass any number promise arrays to it, and it would just suspense until they're all finished. Then you wouldn't even have to care about it being fetch, or axios or whatever, it just does its thing.

sorahn avatar Apr 16 '19 21:04 sorahn