someuser2491
someuser2491

Reputation: 1978

How to fix the error "react use hook cannot be called inside a callback function" using react?

i am using useHook named useGetCompanyByItemId in the return statement.

and so i am getting the error "react hook cannot be called in a callback function"

what i am trying to do?

i am querying for owneditems and shareditems.

and i display both the items. in the Content div i do mapping and there i am calling the useGetCompanyByItemId hook and i get the error.

below is my code,

function Parent() {
    const ownedItems = [{ //somearray of objects}];
    const sharedItems = [{//somearray of objects}];
    const getCurrentItems = () => {
        return ownedItems.concat(sharedItems);
    }

    return (
        <Wrapper>
            {getCurrentItems.length> 0 &&
                <FirstWrapper>
                    //somedivs
                </FirstWrapper>
                <Content>
                    {springProps.map((index) => {
                        const item = getCurrentItems()[index];
                        const isSharedItem = item && item.cognitoId !== cognitoId;
                        const company = useGetCompanyByItemId(item.id); //here is the error
                        return (
                            <>
                                {isSharedItem && 
                                     <div>
                                         <span>company</span>
                                     </div>
                                 }
                            </>
                        }
                    )
                }
            );
        </Content>
    </Wrapper>
);

}

i am not sure how to fix this. i need to pass the item.id for the useGetCompanyById hook and i dont know how to pass that item.id from outside the return statement since that would fix that error.

could someone help me fix this error. thanks.

Upvotes: 3

Views: 4490

Answers (2)

Karthik R
Karthik R

Reputation: 5786

I can see two ways of refactoring here:

Option 1: If you dont have control over the custom hook to modify

Extract the iteration into a component:

const Company = ({itemId, isSharedItem}) => {
   const company = useGetCompanyByItemId(itemId);
   return (<>
      {isSharedItem && 
          (<div>
             <span>{company}</span>
           </div>)
      }
      </>);
}

Use the above component while you iterate.

Option 2: If you have control over the custom hook: I would recommend to refactor custom hook to return a method than object. Sample usage:

const {getCompanyByItemId} = useFetchCompany();

. . .

anywhere in the code, getCompanyByItemId(itemId)

Obvious advantage with above option:

  • Readable and extendable and use it anywhere and even pass around
  • You don't have to worry about refactoring and code splitting just not to break hook rules(do so if it makes sense ofcourse).

Upvotes: 4

Yury Tarabanko
Yury Tarabanko

Reputation: 45106

Extract this logic to a component

function Item({ item, isSharedItem }) {
  const company = useGetCompanyByItemId(item.id);
  return (
    <>
      {isSharedItem && (
        <div>
          <span>company</span>
        </div>
      )}
    </>
  );
}

and then use it in your loop

springProps.map((index) => {
  ...
  return <Item item={item} isSharedItem={isSharedItem} key={index} />

Upvotes: 3

Related Questions