Search code examples
reactjsjsxketting

How to call a hook function into a map in react


I'm using ketting for my React REST client. The library provides hooks to access some data, In my case, this is this hook :

import { useResource } from 'react-ketting';
...
const { loading, error, data } = useResource('https://api.example/article/5');

I have multiples resources and I want to loop on them:

items.map(item => {
const { loading, error, data, resourceState } = useResource(item);

 myItems.push({
  title: data.name,
  onClick: () => go(resourceState.links.get('self').href),
 });
});

But React doesn't accept looping the useResource hook like this.

So I found a dirty solution that I'm not proud of...

import React from 'react';
import { useCollection, useResource } from 'react-ketting';

let myItems = [];

const Collection = ({ resource, go }) => {
  const { items } = useCollection(resource);

  myItems = [];

  return (
    <div>
      {items.map(item => (
        <CollectionItem go={go} resource={item} />
      ))}
      <ElementsUser elements={myItems} />
    </div>
  );
};

const CollectionItem = ({ resource, go }) => {
  const { data, resourceState } = useResource(resource);

  myItems.push({
    title: data.name,
    onClick: () => go(resourceState.links.get('self').href),
  });
  return null;
};

Do you have any tips to deal with that problem?

And is it possible that it causes a :

Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.


Solution

  • Using 1 component per Resource is exactly the pattern that's recommended. I'd even say it's a best practice. Note that a call to useResource will not result in an API call if there was a cached resource state.

    If you find that you are seeing 1 request per iteration, you might want to make sure that your collection returns every member as an embedded resource. If you use the useCollection hook, the request will include a Prefer: transclude=item header to give a hint to the server that embedding might be desired.

    Also, react-ketting will do cleanups on unmount.