如果 props 改变,React 会重新评估 useRef

Bro*_*nBe 1 javascript reactjs react-hooks

子组件有一个依赖于父 props 的 ref 数组。如果道具发生变化而不重新渲染我的子组件,我想更新引用列表。

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>

}
Run Code Online (Sandbox Code Playgroud)

itemsRef如果父更新通过 props 传递新的 menuItem 列表,则不会重新计算。

如何用钩子实现这一点?

Oli*_*ssé 5

您违反了Hooks 规则 Don\xe2\x80\x99t 在循环、条件或嵌套函数内调用 Hooks

\n\n

解决方案可能是使用useRef声明一个实例变量,该变量将是一个数组,并使用ref callback来填充该数组中的元素:

\n\n
const childComponent = props => {\n   const itemsRef = useRef([]);\n   // you can access the elements with itemsRef.current[n]\n\n   return (\n     <ul>\n        {props.menuItems.map((el,i) => \n          <li \n            key={i} \n            ref={el => itemsRef.current[i] = el}\n            children={el.name}\n          />\n        }\n    </ul>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您不希望数组中存在空值,可以添加一个效果来保持数组长度与长度同步(该效果将在refs 回调props.menuItems调用)

\n\n
useEffect(() => {\n  itemsRef.current = itemsRef.current.slice(0, props.menuItems.length);\n}, [props.menuItems]);\n
Run Code Online (Sandbox Code Playgroud)\n