BrownBe
BrownBe

Reputation: 987

React re-evaluate useRef if props change

A Child component has got an array of ref who depend of parent props. I would like to update the ref list if props change without rerender my child component.

const childComponent = (props) =>
{
  // the array of ref item list
  const itemsRef = Array.from({ length: props.menuItems.length }, a => 
  useRef(null));

  useLayoutEffect(()=>
  {
   // enter anim new item ref...

  },[props.menuItem])


  return <ul>
    {props.menuItems.map((el,i) => 
      <li 
        key{i} 
        ref={itemsRef[i]}
        children={el.name}
     >}
  </ul>

}

itemsRef is not recalculate if parent updated pass a new list of menuItem by props.

How achieve this with hooks?

Upvotes: 1

Views: 6086

Answers (1)

Olivier Boiss&#233;
Olivier Boiss&#233;

Reputation: 18173

You are breaking the Rules of Hooks Don’t call Hooks inside loops, conditions, or nested functions

A solution could be to use useRef to declare an instance variable which will be an array and use the ref callback to populate the elements in this array :

const childComponent = props => {
   const itemsRef = useRef([]);
   // you can access the elements with itemsRef.current[n]

   return (
     <ul>
        {props.menuItems.map((el,i) => 
          <li 
            key={i} 
            ref={el => itemsRef.current[i] = el}
            children={el.name}
          />
        }
    </ul>
  );
}

If you don't want null values in the array, you can add an effect to keep the array length in sync with props.menuItems length (the effect will be called after the refs callbacks)

useEffect(() => {
  itemsRef.current = itemsRef.current.slice(0, props.menuItems.length);
}, [props.menuItems]);

Upvotes: 5

Related Questions