React.forwardRef没有它就已经可以了,那还有什么用呢?
React.forwardRef is already possible without it, so what's the use of it?
我对React.forwardRef
这一点感到困惑。正如其 documentation 中所解释的,我知道它的主要用途是 Parent 组件 来访问 DOM Child 组件 的元素。但我已经可以做到这一点,甚至不必使用它。
这是一个代码示例,您可以将其插入 CodeSandbox 并查看它是否有效:
import React, {useRef, useEffect} from "react";
import "./styles.css";
const ChildComponent = (props) => {
useEffect( ()=> {
props.callbackFunction()
})
return(
<div ref={props.fRef}>
{"hello"}
</div>
)
}
export default function App() {
const callbackFunction = () => {
console.log("The parent is now holding the forwarded ref to the child div: ")
console.log(forwardedRef)
}
const forwardedRef = useRef(null)
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<ChildComponent name="gravy" callbackFunction={callbackFunction} fRef={forwardedRef}/>
</div>
);
}
或者这里是这个例子的嵌入。老实说,我对这个有点陌生,我不知道嵌入是如何工作的,也不知道有人摆弄嵌入是否改变了我原来的沙盒,所以我犹豫要不要说。但它就在这里。
Example Forwarding Ref
在示例中,parent App() 组件成功将 ref 传递给 child,child 附加到其呈现 div。呈现后,它会调用 parent 的回调函数。 parent 然后做一个控制台日志,证明其转发的 ref 现在拥有 child 的 div。而这一切都是在没有 React.forwardRef
.
的情况下完成的
那么React.forwardRef
有什么用呢?
您完全正确,您可以按照您所描述的进行操作。不利的一面是您被迫公开 API (即: fRef
道具)以使其正常工作。如果您是构建应用程序的单独开发人员,这没什么大不了的,但是这可能会带来更多问题,例如。如果您正在维护一个带有 public API.
的开源库
在这种情况下,库的使用者将无法访问组件的内部结构,这意味着您必须以某种方式为他们公开组件。您可以简单地按照您在示例中的建议进行操作并添加一个命名道具。事实上,这就是库在 React 16.3 之前所做的。没什么大不了的,但是您必须将其记录下来,以便人们知道如何使用它。理想情况下,您还需要某种每个人都使用的标准,这样就不会造成混淆(许多库使用 innerRef
命名约定),但必须就此达成共识。所以都是可行的,但也许不是理想的解决方案。
使用 forwardRef
,将 ref 传递给组件就像预期的那样工作。 ref
prop 已经在 React 中标准化,因此您无需查看文档来弄清楚如何传递 ref 或它如何工作。但是,您描述的方法完全没问题,如果它满足您的需求,请务必采用它。
如 docs 中所述,它对 高度可重用的组件 很有用,这意味着组件往往像常规 HTML DOM 元素。
这对于具有大量“叶”组件的组件库很有用。你可能用过 Material UI.
示例:
假设您正在维护一个组件库。
您创建了一个 <Button/>
和 <Input/>
组件,可能只是添加了一些默认样式。
请注意这些组件 字面意思 与具有额外步骤的常规 HTML DOM 元素一样。
如果这些组件像常规 HTML DOM 元素一样使用,那么我希望所有道具都相同,包括 ref
,不是吗?
如果要从 <Button/>
组件获取按钮引用,我必须通过 fRef
或 buttonRef
之类的东西来获取它,这不会很乏味吗?
与您的 <Input/>
相同,我是否必须查看文档才能找出要使用的 ref,它类似于 inputRef
?现在还得背?
获取 ref 应该像 <Button ref={}/>
一样简单
问题
如您所知,ref
不会通过 props 传递,因为与 key
一样,React 对它的处理方式不同。
解决方案
React.forwardRef() 解决了这个问题所以我可以使用 <Button ref={}/>
或 <Input ref={}/>
.
我对React.forwardRef
这一点感到困惑。正如其 documentation 中所解释的,我知道它的主要用途是 Parent 组件 来访问 DOM Child 组件 的元素。但我已经可以做到这一点,甚至不必使用它。
这是一个代码示例,您可以将其插入 CodeSandbox 并查看它是否有效:
import React, {useRef, useEffect} from "react";
import "./styles.css";
const ChildComponent = (props) => {
useEffect( ()=> {
props.callbackFunction()
})
return(
<div ref={props.fRef}>
{"hello"}
</div>
)
}
export default function App() {
const callbackFunction = () => {
console.log("The parent is now holding the forwarded ref to the child div: ")
console.log(forwardedRef)
}
const forwardedRef = useRef(null)
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<ChildComponent name="gravy" callbackFunction={callbackFunction} fRef={forwardedRef}/>
</div>
);
}
或者这里是这个例子的嵌入。老实说,我对这个有点陌生,我不知道嵌入是如何工作的,也不知道有人摆弄嵌入是否改变了我原来的沙盒,所以我犹豫要不要说。但它就在这里。 Example Forwarding Ref
在示例中,parent App() 组件成功将 ref 传递给 child,child 附加到其呈现 div。呈现后,它会调用 parent 的回调函数。 parent 然后做一个控制台日志,证明其转发的 ref 现在拥有 child 的 div。而这一切都是在没有 React.forwardRef
.
那么React.forwardRef
有什么用呢?
您完全正确,您可以按照您所描述的进行操作。不利的一面是您被迫公开 API (即: fRef
道具)以使其正常工作。如果您是构建应用程序的单独开发人员,这没什么大不了的,但是这可能会带来更多问题,例如。如果您正在维护一个带有 public API.
在这种情况下,库的使用者将无法访问组件的内部结构,这意味着您必须以某种方式为他们公开组件。您可以简单地按照您在示例中的建议进行操作并添加一个命名道具。事实上,这就是库在 React 16.3 之前所做的。没什么大不了的,但是您必须将其记录下来,以便人们知道如何使用它。理想情况下,您还需要某种每个人都使用的标准,这样就不会造成混淆(许多库使用 innerRef
命名约定),但必须就此达成共识。所以都是可行的,但也许不是理想的解决方案。
使用 forwardRef
,将 ref 传递给组件就像预期的那样工作。 ref
prop 已经在 React 中标准化,因此您无需查看文档来弄清楚如何传递 ref 或它如何工作。但是,您描述的方法完全没问题,如果它满足您的需求,请务必采用它。
如 docs 中所述,它对 高度可重用的组件 很有用,这意味着组件往往像常规 HTML DOM 元素。
这对于具有大量“叶”组件的组件库很有用。你可能用过 Material UI.
示例:
假设您正在维护一个组件库。
您创建了一个 <Button/>
和 <Input/>
组件,可能只是添加了一些默认样式。
请注意这些组件 字面意思 与具有额外步骤的常规 HTML DOM 元素一样。
如果这些组件像常规 HTML DOM 元素一样使用,那么我希望所有道具都相同,包括 ref
,不是吗?
如果要从 <Button/>
组件获取按钮引用,我必须通过 fRef
或 buttonRef
之类的东西来获取它,这不会很乏味吗?
与您的 <Input/>
相同,我是否必须查看文档才能找出要使用的 ref,它类似于 inputRef
?现在还得背?
获取 ref 应该像 <Button ref={}/>
问题
如您所知,ref
不会通过 props 传递,因为与 key
一样,React 对它的处理方式不同。
解决方案
React.forwardRef() 解决了这个问题所以我可以使用 <Button ref={}/>
或 <Input ref={}/>
.