在另一个组件的渲染函数中直接使用React.forwardRef方法是否安全-

范例-

function Link() {
  // --- SOME EXTENSIVE LOGIC AND PROPS CREATING GOES HERE ---
  // --- OMITTED FOR SIMPLICITY ---

  // TO DO: Remove forward ref as soon Next.js bug will be fixed -
  // https://github.com/zeit/next.js/issues/7915

  // Please note that Next.js Link component uses ref only to prefetch link
  // based on its availability in view via IntersectionObserver API -
  // https://github.com/zeit/next.js/blob/canary/packages/next/client/link.tsx#L119
  const TempShallow = React.forwardRef(props =>
    cloneElement(child, {
      ...props,
      ...baseProps,
      onClick: handleClick
    })
  );

  return (
    <NextLink href={href} as={as} prefetch={prefetch} passHref {...otherProps}>
      <TempShallow />
    </NextLink>
  );
}

如您所见,这是Next.js v9-https://github.com/zeit/next.js/issues/7915中错误的临时解决方法。

最佳答案

当心forwardRef影响对帐:始终在父级重新渲染时重新创建元素。


function App() {
  const [,setState] = useState(null);
  const Input = React.forwardRef((props, ref) => <input {...props} />)
  return (
    <div className="App">
      <h1>Input something into inputs and then click button causing re-rendering</h1>
      <Input placeholder="forwardRef" />
      <input placeholder="native" />
      <button onClick={setState}>change state to re-render</button>
    </div>
  );
}

您可能会看到单击forwardRef按钮后,已删除输入并重新创建输入,因此其值变为空。

不确定这对<Link>是否重要,但总的来说,这意味着您希望每个生命周期仅运行一次(例如,以componentDidMountuseEffect(...,[])提取数据)会更频繁地发生。

因此,如果在这种副作用和 mock 警告之间进行选择,我宁愿忽略警告。或创建自己的<Link >不会引起警告。

[UPD]遗漏了一件事:在这种情况下,React通过引用检查forwardRef。因此,如果您从forwardRef中创建render(因此在引用上相同),则不会重新创建它:
const Input = React.forwardRef((props, ref) => <input {...props} />)

function App() {
  const [,setState] = useState(null);
  return (
    <div className="App">
      <h1>Input something into inputs and then click button causing re-rendering</h1>
      <Input placeholder="forwardRef" />
      <input placeholder="native" />
      <button onClick={setState}>change state to re-render</button>
    </div>
  );
}


但是我仍然相信,忽略警告比引入这种解决方法更安全。

上面的代码对我而言可读性较差,并且令人困惑(“为什么不完全处理ref?这是故意的吗?为什么此forwardRef在这里而不在组件的文件中?”)

关于javascript - 直接在render函数中使用React.forwardRef,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57337436/

10-11 06:15