[英]How to use React.forwardRef with TypeScript when using different html elements in the render
[英]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>
是否重要,但总的来说,这意味着您希望每个生命周期仅运行一次(例如,在componentDidMount
或useEffect(...,[])
获取数据)会发生很多更频繁。
因此,如果在这种副作用和嘲笑警告之间进行选择,我宁愿忽略警告。 或创建自己的<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.