react ref 常見用法

react ref

ref 主要在于提供父組件能直接操作子組件的能力,這里子組件可能是 dom 元素也可能是 react 組件的實例,不同于 props 形式的操作子組件,ref 可以直接調(diào)用子組件實例上的方法或?qū)傩?。下面介紹了一些常用的用法:

什么時候使用 ref

  • 用來操作原始 dom 元素的,獲取尺寸、獲取焦點等
  • 觸發(fā)命令式的動畫
  • 用來整合第三方 dom 庫

創(chuàng)建 ref 有以下兩種方式

  • createRef
  • callback ref

React 16.3 之后版本推薦使用 createRef 或 useRef 方式創(chuàng)建,React 16.3 以前版本使用 callback ref 方式

ref 的用在不同類型節(jié)點上有不同的值

  • ref 屬性用在 html dom 上,獲取的值是 dom 對象
  • ref 屬性用在自定義類組件上,獲取的值是組件的實例
  • ref 屬性不能用在函數(shù)組件上的,但可以通過 forwardRef 或 自定義屬性傳遞 ref

使用場景

父組件 子組件
函數(shù)組件 類組件
函數(shù)組件 函數(shù)組件
函數(shù)組件 dom 元素

父組件是類組件的時候是相同的

createRef 在 dom 元素上

  • 通過 useRef hook 或 createRef 創(chuàng)建 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 創(chuàng)建 ref 對象
  • 直接用在自定義類組件的 ref 屬性上
  • 獲取的值綁定在 ref 的 current 屬性上
  • 獲取的是子組件的實例,可以直接調(diào)用子組件公開的屬性和方法
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 用在自定義函數(shù)組件上

  • 通過 useRef hook 或 createRef 創(chuàng)建 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 用在函數(shù)組件上

  • 在 ref 屬性上綁定 fn 類型的值
  • ref 不會有 current 屬性
  • 直接用在子組件的 ref 屬性上,但子組件必須使用 forwardRef 包裹
  • 子組件里的 ref 要綁定在下一級的 dom 元素或子組件上
  • 獲取的值取決于子組件里 ref 的使用
  • 也可以通過自定義屬性傳遞 ref,脫離 forwardRef
import React, { forwardRef, useEffect } from "react";

// 函數(shù)組件里使用 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} />
    )
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容