美文网首页
react ref 常见用法

react ref 常见用法

作者: 莫帆海氵 | 来源:发表于2022-02-09 16:06 被阅读0次

    react ref

    ref 主要在于提供父组件能直接操作子组件的能力,这里子组件可能是 dom 元素也可能是 react 组件的实例,不同于 props 形式的操作子组件,ref 可以直接调用子组件实例上的方法或属性。下面介绍了一些常用的用法:

    什么时候使用 ref

    • 用来操作原始 dom 元素的,获取尺寸、获取焦点等
    • 触发命令式的动画
    • 用来整合第三方 dom 库

    创建 ref 有以下两种方式

    • createRef
    • callback ref

    React 16.3 之后版本推荐使用 createRef 或 useRef 方式创建,React 16.3 以前版本使用 callback ref 方式

    ref 的用在不同类型节点上有不同的值

    • ref 属性用在 html dom 上,获取的值是 dom 对象
    • ref 属性用在自定义类组件上,获取的值是组件的实例
    • ref 属性不能用在函数组件上的,但可以通过 forwardRef 或 自定义属性传递 ref

    使用场景

    父组件 子组件
    函数组件 类组件
    函数组件 函数组件
    函数组件 dom 元素

    父组件是类组件的时候是相同的

    createRef 在 dom 元素上

    • 通过 useRef hook 或 createRef 创建 ref 对象
    • 直接用在 dom 元素的 ref 属性上
    • 获取的值绑定在 ref 的 current 属性上
    • 获取的是 dom 对象,可以直接操作 dom 的属性和方法
    import React, { useEffect, useRef } from "react";
    
    const RefInDomElement = () => {
        // 和使用 React.createRef() 一样
        const avatarRef = useRef()
    
        useEffect(() => {
            console.log(avatarRef.current.src)
        }, [])
    
        return(
            <img src="http://file04.shouwuapp.com/1/202201/f2254b0777b8483b47bad13e357dd099.jpg?x-oss-process=style/middle" alt="" ref={avatarRef} />
        )
    }
    
    export default RefInDomElement
    

    createRef 用在自定义类组件上

    • 通过 useRef hook 或 createRef 创建 ref 对象
    • 直接用在自定义类组件的 ref 属性上
    • 获取的值绑定在 ref 的 current 属性上
    • 获取的是子组件的实例,可以直接调用子组件公开的属性和方法
    import React, { useEffect, useRef } from "react";
    
    const RefInCustomComponent = () => {
        const caRef = useRef()
    
        useEffect(() => {
            console.log(caRef.current.setState({a: 1}))
        }, [])
    
        return(
            <CustomAvatar ref={caRef} />
        )
    }
    
    export default RefInCustomComponent
    
    
    class CustomAvatar extends React.Component {
        render() {
            return(
                <img src="http://file04.shouwuapp.com/1/202201/f2254b0777b8483b47bad13e357dd099.jpg?x-oss-process=style/middle" alt="" />
            )
        }
    }
    

    createRef 用在自定义函数组件上

    • 通过 useRef hook 或 createRef 创建 ref 对象
    • 获取的值绑定在 ref 的 current 属性上
    • 直接用在子组件的 ref 属性上,但子组件必须使用 forwardRef 包裹
    • 子组件里的 ref 要绑定在下一级的 dom 元素或子组件上
    • 获取的值取决于子组件里 ref 的使用
    import React, { forwardRef, useEffect, useRef } from "react";
    
    const RefInFunctionComponent = () => {
        let avatarRef = useRef()
        useEffect(() => {
            console.log(avatarRef.current.src)
        }, [])
    
        return (
            <FAvatar ref={avatarRef} />
            // 可以使用自定义属性传递 ref
            // <Avatar someRef={avatarRef} />
        )
    }
    
    export default RefInFunctionComponent
    
    const avatar_URL = 'http://file04.shouwuapp.com/1/202201/f2254b0777b8483b47bad13e357dd099.jpg?x-oss-process=style/middle'
    
    const FAvatar = forwardRef(({}, ref) => {
        return(
            <img src={avatar_URL} alt="" ref={ref} />
        )
    })
    
    const Avatar = ({ someRef }) => {
        return(
            <img src={avatar_URL} alt="" ref={someRef} />
        )
    }
    
    

    callback ref 用在 dom 元素上

    • 在 ref 属性上绑定 fn 类型的值
    • ref 不会有 current 属性
    • 直接用在 dom 的 ref 属性上
    • 获取的是 dom 对象,可以直接操作 dom 的属性和方法
    import React, { useEffect } from "react";
    
    // callback ref in html dom element
    
    const CallbackRefInDomElement = () => {
        let avatarRef = null
        useEffect(() => {
            console.log(avatarRef)
        }, [])
    
        return (
            <img src={avatar_URL} alt="" ref={ref => avatarRef = ref} />
        )
    }
    
    export default CallbackRefInDomElement
    
    const avatar_URL = 'http://file04.shouwuapp.com/1/202201/f2254b0777b8483b47bad13e357dd099.jpg?x-oss-process=style/middle'
    

    callback ref 用在自定义类组件上

    • 在 ref 属性上绑定 fn 类型的值
    • ref 不会有 current 属性
    • 直接用在子组件的 ref 属性上
    • 获取的是子组件的实例
    import React, { forwardRef, useEffect } from "react";
    
    const CallbackRefInCustomComponent = () => {
        let avatarRef = null
        useEffect(() => {
            console.log(avatarRef)
        }, [])
    
        return (
            <CAvatar ref={ref => avatarRef = ref} />
        )
    }
    
    export default CallbackRefInCustomComponent
    
    const avatar_URL = 'http://file04.shouwuapp.com/1/202201/f2254b0777b8483b47bad13e357dd099.jpg?x-oss-process=style/middle'
    
    class CAvatar extends React.Component {
        render() {
            return(
                <img src={avatar_URL} alt="" />
            )
        }
    }
    

    callback ref 用在函数组件上

    • 在 ref 属性上绑定 fn 类型的值
    • ref 不会有 current 属性
    • 直接用在子组件的 ref 属性上,但子组件必须使用 forwardRef 包裹
    • 子组件里的 ref 要绑定在下一级的 dom 元素或子组件上
    • 获取的值取决于子组件里 ref 的使用
    • 也可以通过自定义属性传递 ref,脱离 forwardRef
    import React, { forwardRef, useEffect } from "react";
    
    // 函数组件里使用 callback ref
    
    const CallbackRefInFunctionComponent = () => {
        let avatarRef = null
        useEffect(() => {
            console.log(avatarRef)
        }, [])
    
        return (
            <FAvatar ref={ref => avatarRef = ref} />
            // 可以使用自定义属性传递 ref
            // <Avatar someRef={ref => avatarRef = ref} />
        )
    }
    
    export default CallbackRefInFunctionComponent
    
    const avatar_URL = 'http://file04.shouwuapp.com/1/202201/f2254b0777b8483b47bad13e357dd099.jpg?x-oss-process=style/middle'
    
    const Avatar = ({ someRef }) => {
        return(
            <img src={avatar_URL} alt="" ref={someRef} />
        )
    }
    
    const FAvatar = forwardRef(({}, ref) => {
        return(
            <img src={avatar_URL} alt="" ref={ref} />
        )
    })
    

    相关文章

      网友评论

          本文标题:react ref 常见用法

          本文链接:https://www.haomeiwen.com/subject/fumwhrtx.html