ForwardRef useImperativeHandle方法怎么使用
本文小编为大家详细介绍“ForwardRef useImperativeHandle方法怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“ForwardRef useImperativeHandle方法怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
一、获取Ref的方式
使用字符串
使用函数
使用Ref对象(最常见)
使用createRef
export class RefTest extends React.Component { currentDom: React.RefObject<HTMLDivElement> = React.createRef(); currentChildren: React.LegacyRef<Children> = React.createRef(); render() { console.log(this.currentChildren, this.currentDom); return ( <> <div ref = { this.currentDom }>你好</div> <Children ref = { this.currentChildren}></Children> </> ) }}
使用useRef
export const RefTest = () => { const currentDom = useRef(null); const currentChildren = useRef(null); useEffect(() => { console.log(currentChildren, currentDom, '这里也可以打印出来了'); },[]) return ( <> <div ref = { currentDom }>你好</div> <Children ref = { currentChildren }></Children> </> )}
二、Ref实现组件通信
既然ref可以获取到子组件的实例,那么就可以拿到子组件上的状态和方法,从而可以实现组件之间的通信
来个极简版
import React, { useEffect } from 'react';class Son extends React.Component{ state={ sonValue:'' } render(){ return <div> <div>子组件的信息: {this.state.sonValue}</div> <div>对父组件说</div> <input onChange{(e)=>this.props.setFather(e.target.value)}/> </div> }}export default function Father(){const [ fatherValue , setFatherValue ] = React.useState('')const sonRef = React.useRef(null)return <div> <div>父组件的信息: {fatherValue}</div> <div>对子组件说</div> <input onChange = { (e) => sonRef.current.setState( {sonValue: e.target.value})}/> <Son ref={sonRef} setFather={setFatherValue}/> </div>}
三、ForwardRef
上面说的三种都是组件去获取其DOM元素或者子组件的实例,当开发变得复杂时,我们可能有将ref跨层级捕获的需求,也就是可以将ref进行转发
比如跨层级获取ref信息
来个例子, 我们希望能够在GrandFather组件获取到Son组件中
![图片转存失败,建议将图片保存下来直接上传 import React from 'react';interface IProps { targetRef: React.RefObject<HTMLDivElement> otherProps: string}interface IGrandParentProps { otherProps: string}class Son extends React.Component<IProps> { constructor(props) { super(props); console.log(props,'son中的props'); } render() { // 最终目标是获取该DOM元素的信息 return <div ref= { this.props.targetRef }>真正目的是这个</div> }}class Farther extends React.Component<IProps> { constructor(props) { super(props) console.log(props, 'father中的props'); } render() { return ( // 继续将ref传给Son <Son targetRef={this.props.targetRef} {...this.props} /> ) }}// 在这里使用了forwardRef, 相当于把传入的ref转发给Father组件const ForwardRef = React.forwardRef((props: IGrandParentProps, ref: React.RefObject<HTMLDivElement>) => <Farther targetRef={ref} {...props}/>) image.png(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5d49e7ff4ec940b28dcb3a780fd5c0a7~tplv-k3u1fbpfcp-watermark.image?)export class GrandFather extends React.Component { currentRef:React.RefObject<HTMLDivElement> = React.createRef(); componentDidMount() { // 获取到的Ref信息 console.log(this.currentRef, 'componentDidMount'); } render() { return ( <ForwardRef ref={this.currentRef} otherProps = '正常传递其他props' /> ) }}]()
打印结果: 其实就是利用了forwardRef,把 ref 变成了可以通过 props 传递和转发
四、 useImperativeHandle
上面我们一直说的都是获取子组件的实例,但是实际上我们函数组件是没有实例的,故我们需要借助useImperativeHandle, 使用forwardRef+useImperativeHandle就可以在函数组件中流畅地使用ref
useImperativeHandle可以传入三个参数:
ref: 可以接受forwardRef传入的ref
handleFunc: 返回值作为暴露给父组件的ref对象
deps: 依赖项,当依赖项改变的时候更新形成的ref对象
看完参数其实就能够清楚地知道它的作用了,可以通过forwardRef+useImperativeHandle自定义获取到的ref信息
再来两个简单例子:
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react"const ForwardItem = forwardRef((props, ref) => { const [sonValue, setSonValue] = useState('修改之前的值'); useImperativeHandle(ref, () => ({ setSonValue, })) return ( <div>子组件的值: {sonValue}</div> )})export const Father = () => { const testRef = useRef(null); useEffect(() => { console.log(testRef.current, 'ref获取到的信息') }) const changeValue = () => { const DURATION = 2000; setTimeout(() => { testRef.current.setSonValue('我已经修改值啦') },DURATION) } return ( <> <ForwardItem ref={ testRef }/> <button onClick={() => changeValue()}>2s后修改子组件ForwardItem的值</button> </> )}
父组件希望直接调用函数子组件的方法
这里让useImperativeHandle形成了有setSonValue的ref对象,然后再在父组件调用该方法
父组件希望获取到子组件的某个DOM元素
const ForwardItem = forwardRef((props, ref) => { const elementRef: RefObject<HTMLDivElement> = useRef(); useImperativeHandle(ref, () => ({ elementRef, })) return ( <div ref = { elementRef }>我是一个子组件</div> )})export const Father = () => { const testRef = useRef(null); useEffect(() => { console.log(testRef.current, 'ref获取到的信息') }) return ( <> <ForwardItem ref={ testRef }/> </> )}
读到这里,这篇“ForwardRef useImperativeHandle方法怎么使用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341