简体   繁体   English

如果道具发生变化,请重新评估useRef

[英]React re-evaluate useRef if props change

A Child component has got an array of ref who depend of parent props. Child组件具有一系列依赖于父项prop的ref。 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. 如果更新的父项通过props传递了一个新的menuItem列表,则不会重新计算itemsRef

How achieve this with hooks? 如何用钩子做到这一点?

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 : 一个解决方案可能是使用useRef声明一个实例变量 ,该实例变量将是一个数组,并使用ref callback来填充此数组中的元素:

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) 如果不想在数组中使用null值,则可以添加一个效果以使数组长度与props.menuItems length保持同步(该效果将在refs回调之后调用)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM