在另一个组件的渲染函数中直接使用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(...,[])
提取数据)会更频繁地发生。因此,如果在这种副作用和 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/