繁体   English   中英

直接在render函数中使用React.forwardRef

[英]Using React.forwardRef inside render function directly

在另一个组件的渲染函数中直接使用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(...,[])获取数据)会发生很多更频繁。

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

[UPD]遗漏了一件事:在这种情况下,React通过引用检查forwardRef 因此,如果您从render制作forwardRef (因此在引用上相同),则不会重新创建它:

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此处而不在组件的文件中?”)

我同意skyboyer,我要补充一点,可能可以在render函数之外创建forwardRef组件,以避免重新创建每个渲染组件。 被检查。

const TempShallow = React.forwardRef(({ child, ...props }) => React.cloneElement(child, props))

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


  return (
    <NextLink href={href} as={as} prefetch={prefetch} passHref {...otherProps}>
      <TempShallow {...props} {...baseprops} child={child} onClick={onClick} />
    </NextLink>
  )
}

暂无
暂无

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

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