reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.59k stars 1.14k forks source link

RTK Query: operating on collections of single resource requests? #2185

Open ChuckJonas opened 2 years ago

ChuckJonas commented 2 years ago

Let's say I have a very simple use case where I need to show a list of contacts by hitting this endpoint:

GET api/contacts/:id

Using RTK query hooks, it would look something like this:

const ContactsList = (contactIds: string[] ) => {
    return contactIds.map(id => <ContactsDisplay id={id} />);
}

const ContactsDisplay = (id: string ) => {
  const {data, loading, error} = useContactQuery(id);
  if(!data){
    return <div>loading</div>
  }
  return (
    <div>Name: {data.name} Age:{data.age}</div>
  );
}

However, I'm struggling how to use RTKQuery when I get requirements where I actually need to aggregate/derive some data from ALL the retrieved contacts in the parent component.

Example use case:

Add "average age" to the ContactsList

The imperative version, would look something like this:

const ContactsList = (contactIds: string[]) => {
   const [contacts, setContacts] = useState<Contact[]>([]);

    useEffect(() => {
       const contactPromises = contactIds.map(queryContact);  //queryContact returns `Promise<Contact>`
       Promise.all(contactPromises).then(setContacts);
    }, [contactIds]);

   const averageAge = contacts.reduce((total, item) => total + item.age, 0) / contacts.length;
   const contactList = contactIds.map(item => <ContactsDisplay contact={item} />); // refactored to accept a "Contact" record
   return (
      <>
         <span>Average Age: {averageAge}</span>
         {contactList}
      </>
    )
}

Any help / direction would be appreciated.

ChuckJonas commented 2 years ago

Looks like a similar discussion is outlined here.

It would be great if RTK Query supported useQueries