3

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.

2 Answers 2

4

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).
Sign up to request clarification or add additional context in comments.

Comments

3

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} />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.