使用前向引用和使用固定处理的示例.在 React 的典型数据流中,道具是父子组件交互的唯一方式,要修改子组件,可以使用新道具重新渲染它。
除了典型的 React 数据流之外,在某些情况下(例如,专注于一个 DOM 元素等)为了修改子组件,我们可能需要另一种方式:Ref 方式。引用提供了一种访问 DOM 节点或 React 元素的方法。
*由于本文使用了功能组件,因此我将重点介绍它们。让我们从第一个示例开始,以便我们可以更好地理解。
示例一:对焦输入
当用户单击按钮时将光标聚焦在输入上
假设我们有一个输入字段,我们希望当用户开始键入或单击按钮时光标聚焦于该字段。仅修改输入字段更有意义,而不是更改状态(通过 props)导致组件重新渲染,这可以通过创建 ref 来完成。
我们可以使用 useRef() 钩子来创建一个 ref,该引用返回一个可变对象,其当前属性设置为我们传递给钩子的初始值,并在 DOM 元素<输入>上使用它:
控制台.log(输入引用)
很简单,当用户开始键入时,输入字段是聚焦的,但是由于某种原因,当用户单击按钮时,此输入字段也应该具有焦点,我们的输入字段位于名为 InputWrapper 的反应子组件中。
也许我们会尝试这样做:
这行不通,因为默认情况下,refs只在原生HTML元素中工作,我们不能为React组件提供引用(在我们的例子中是InpinTraapper),并且由于函数组件没有实例,我们也可能不会在其上使用属性,这意味着:ref
常规函数或类组件不接收参数,并且 ref 在 props 中也不可用。ref
因此,我们需要将输入包装器传递到 forwardRef 中,它接收传递给功能组件的 prop 和引用,并返回 JSX。它的元素。
const InputWrapper = forwardRef((props, ref) => {…})
创建 ref 并将其传递给应用组件内的输入包装器
应用内触发焦点的按钮事件处理程序
将引用转发到输入 DOM 元素
通过这样做,我们告诉 React,这个组件可以接收一个 ref,而我们的第二个参数将是传入的 ref。 InputWrapperrefforwardRef
*在类组件上也可以进行引用转发
示例二:播放/暂停视频和对焦输入
使用使用对多个引用使用简化处理
在这个例子中,我们有一个视频播放器和2个播放/暂停视频的按钮,当我们点击播放按钮时,我们还想聚焦下面的输入字段,这意味着我们将有多个引用(视频,输入)。
如何转发多个引用?
第一个解决方案:我们可以创建 ref 并将它们传递到一个对象中,然后使用与上面示例中相同的逻辑。
家长应用程序:
儿童视频包装:
第二种解决方案:使用反应钩子useImperativeHandle
使用反转手处理自定义在使用 ref 时向父组件公开的实例值,它应该与转发引用一起使用。
这听起来可能令人困惑,让我们先更新组件:
在应用程序内创建一个引用并将其传递给视频包装器:
在视频包装器组件中,我们可以确定哪些属性将使用使用在引用上公开翻译手柄钩子(您可以随意调用它们:播放视频,焦点此输入,暂停Me等)
上面的代码是什么意思?我们在钩子内添加方法,然后它们将被其父级公开和使用。useImperative Handle
如上面的示例所示,我们可以使用钩子 forwardRef 访问 React 函数子组件的基础 DOM 元素,我们可以处理多个引用,甚至可以通过将引用传递给其子级来修改父组件有权访问的引用。
注意:使用ImperativeHandle启用了命令性代码,这与 React 的声明性本质背道而驰,这使得它非常独特。由于这个原因,除非绝对需要,否则通常建议避免这种钩子。
您可以查看结果并在此处尝试。