skip to Main Content

Currently I am mapping through a list in my react component:

const items = useMemo(() => {
  return items.map(item => {
    const element = useSearchResult(item)
  })
  ...
}, [dependencies])

I am aware that calling a hook inside a useMemo is bad practice and should not be done. However, how can I solve this issue?

I thought of doing this:

const element = (item) => useSearchResult(item)

const items = useMemo(() => {
  return items.map(item => {
    element(item)
  })
  ...
}, [dependencies])

I don’t think this solves the issue of not calling a hook inside a useMemo.

useSearchResult will return a JSX element which is based on the item prop it receives.

const useSearchResult = ({ item }) => {
  return (
    <div>
      {item.name}
      {item.id}
    </div>
  )
}

2

Answers


  1. const useSearchResult = ({item}) => {
     return (
       <div>
         {item.name}
         {item.id}
        </div>
     )
    }
    

    Since this code does not call any hooks (eg, useState, useEffect), it is not a custom hook. It does not need to follow the rules of hooks, meaning you can safely call it as many times as you like, and you can change the number of times on each render. The only thing you should do is change the name of it so no one (neither humans, nor automated tools like eslint) mistakenly thinks it needs to follow the rules of hooks.

    Login or Signup to reply.
  2. useSearchResult isn’t actually a React hook, it appears to be a regular React component, e.g. a function that returns JSX. You should rename to SearchResult and render it as JSX directly.

    Example:

    const SearchResult = ({ item }) => {
      return (
        <div>
          {item.name}
          {item.id}
        </div>
      );
    };
    
    return (
      ...
      {items.map(item => <SearchResult key={item.id} item={item} />)}
      ...
    );
    

    React will handle rerendering when the items "dependency" updates. If there is an issue with rerendering too often, then memoize the items array value.

    const memoizedItems = useMemo(() => {
      // compute and return stable items array
    }, [/* dependencies */]);
    
    ...
    
    return (
      ...
      {memoizedItems.map(item => <SearchResult key={item.id} item={item} />)}
      ...
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search