Javascript 直接在渲染函数中使用React.forwardRef

Javascript 直接在渲染函数中使用React.forwardRef,javascript,reactjs,next.js,Javascript,Reactjs,Next.js,直接在另一个组件的渲染函数中使用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.c

直接在另一个组件的渲染函数中使用
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错误修复后尽快删除forward ref-
// https://github.com/zeit/next.js/issues/7915
//请注意,Next.js Link组件仅使用ref来预取链接
//基于通过IntersectionObserver API查看的可用性-
// https://github.com/zeit/next.js/blob/canary/packages/next/client/link.tsx#L119
const tempshalf=React.forwardRef(props=>
克隆元素(儿童{
…道具,
…基本道具,
onClick:handleClick
})
);
返回(
);
}

正如您所看到的,这是Next.js v9中一个bug的临时解决办法。

注意
forwardRef
影响对账:元素总是在父级重新渲染时重新创建

但我仍然认为,忽视警告比引入这样一种解决办法更安全


上面的代码对我来说可读性较差,令人困惑(“为什么ref根本没有被处理?这是故意的吗?为什么forwardRef在这里而不在组件的文件中?”)

我同意skyboyer,我要补充的是,可以在渲染函数之外创建
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>
  )
}

const tempshalf=React.forwardRef(({child,…props})=>React.cloneElement(child,props))
函数链接(){
//---这里有一些广泛的逻辑和道具---
//---为简单起见省略---
//要做的事情:在Next.js错误修复后尽快删除forward ref-
// https://github.com/zeit/next.js/issues/7915
//请注意,Next.js Link组件仅使用ref来预取链接
//基于通过IntersectionObserver API查看的可用性-
// https://github.com/zeit/next.js/blob/canary/packages/next/client/link.tsx#L119
返回(
)
}

我错过了一件关于
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>
  );
}

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>
  )
}