最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何深入理解React的ref 屬性

 更新時間:2021年05月15日 10:09:49   作者:lovin  
關于 Refs ,React 官網(wǎng)講解的對于新手來說不太友好,還是自己一字一句解讀后并以代碼驗證的方式后真正理解的.

概述

首先,Refs 和 ref 是兩個概念,Refs 是 React 提供的可用特定 API 創(chuàng)建的一個對象。該對象的結(jié)構(gòu)如下:

這個對象只有一個屬性就是 current ,那么這個對象是用來干嘛的呢?

Refs 允許我們訪問 DOM 節(jié)點或在 render 方法中創(chuàng)建的 React 元素。(DOM節(jié)點就是指原生DOM元素,在render()方法中創(chuàng)建的 React 元素就是指 React 的類組件元素)

我們可以想象這樣一個需求,兩個兄弟元素,一個是 div ,一個是 button?,F(xiàn)在想實現(xiàn)點擊 button,改變 div 的背景顏色。在原生的 DOM 技術中,我們可以在 button 的點擊函數(shù)里使用 document.querySelector('xxx') 的方式選中 div 節(jié)點,然后改變其背景樣式。但是無論是在 Vue 還是 React 這樣的框架中,頁面元素都是動態(tài)生成的,無法使用 DOM API 獲取的方式。而且 React 中大部分操作的元素不是 原生DOM元素,而是 React 元素。 那么如何選擇到某一個 原生DOM元素 或者 React 元素呢?

其實,理論上,我們不需要進行任何的選擇操作,這樣會失去前端框架中組件獨立的概念。一般情況下是通過 組件通信 的方式進行事件的處理的。上述的情況可以使用 EventBus 的方式進行組件通信,button 的點擊事件中進行自定義事件的觸發(fā),在 div 中進行自定義事件的監(jiān)聽,讓 button 以事件通知的方式告知 div 讓其改變背景色,而不是在 button 的事件中直接獲取 div 進行操作。

但是 React 為我們提供了直接訪問 DOM元素 和 React 元素的方式,就是通過 Refs。使用的方式很簡單,就是,為想要訪問的元素上添加 ref 屬性,將 Refs 對象附加到 ref 屬性上,那么此時 Refs 對象的 current 屬性就不再是空,而是對應的 DOM元素 或 React 元素實例了。

1. Refs 對象的創(chuàng)建

在 React 中,創(chuàng)建 Ref 對象的方式有兩種:

1.1 React.createRef()

使用 React.createRef() 的方式可以創(chuàng)建一個 Ref 對象,可通過附加到 ref 屬性上訪問一個 原生DOM元素 或者 class 組件。
這種方式既可以在函數(shù)組件中使用,也可以在class組件中使用。

1.2 React.useRef(initialValue)

在 React 16.8 中新增了 Hook 后,又多了一個可以創(chuàng)建 Ref 對象的 Hook。即 React.useRef(initialValue)。
useRef 返回一個可變的 ref 對象,其 .current 屬性被初始化為傳入的參數(shù)(initialValue)。返回的 ref 對象在組件的整個生命周期內(nèi)保持不變。
這種方式只能在函數(shù)組件中使用。

2. ref 屬性的使用

ref 屬性只能被添加到 原生DOM元素 或者 React的 class 組件上。不能在 函數(shù)組件 上使用 ref 屬性,因為函數(shù)組件沒有實例。

若想在函數(shù)組件上使用 ref 屬性,可以通過 React.forwardRef 將 Ref 轉(zhuǎn)發(fā)到函數(shù)組件內(nèi)部的 原生 DOM 元素上。

2.1 為原生DOM元素添加 ref

class類組件內(nèi)部

class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <div ref={this.myRef}>我是App組件</div>
        )
    }
}

函數(shù)組件內(nèi)部

const App = ()=>{
    const myRef = React.useRef(null)
    //const myRef = React.createRef() 兩種創(chuàng)建 ref 對象的方式都可以
    React.useEffect(()=>{
        console.log(myRef)
        console.log(myRef.current)
    },[]) //模擬生命周期
    return (
        <div ref={myRef}>我是函數(shù)組件內(nèi)部使用ref的div</div>
    )
}

2.2 為class組件添加 ref

class ClassChild extends React.Component{
    render(){
        return (
            <div>我是App組件的 class 子組件 ClassChild</div>
        )
    }
}

class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <ClassChild ref={this.myRef}/>
        )
    }
}

2.3 為class組件轉(zhuǎn)發(fā)的原生DOM元素添加 ref

ref 轉(zhuǎn)發(fā)原理就是將父組件中定義的 ref 對象當作普通屬性的方式傳遞給子組件,然后子組件通過 props 接收再賦值給自己 DOM元素 上。

class ClassChild extends React.Component{
    render(){
        return (
            <div ref={this.props.refProp}>我是App組件的 class 子組件 ClassChild</div> //添加了 ref
        )
    }
}

class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <ClassChild refProp={this.myRef}/> //作為普通屬性傳遞
        )
    }
}

2.4 為函數(shù)組件轉(zhuǎn)發(fā)的原生DOM元素添加 ref

根據(jù)class類組件轉(zhuǎn)發(fā)的原理,我想到的實現(xiàn)方法如下:

const FunChild = (props)=>{
    return (
        <div ref={props.refProp}>我是函數(shù)組件 FunChild</div>
    )
}
class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <FunChild refProp={this.myRef}/>
        )
    }
}

這種實現(xiàn)方式是可以的,但這不是在 函數(shù)組件 上直接使用 ref 屬性的方式,React 提供了在函數(shù)組件上直接使用 ref 的方式,就是使用 React.forwardRef 創(chuàng)建 React 元素。

React.forwardRef

const FunChild = React.forwardRef((props, ref)=>{
    return (
        <div ref={ref}>我是函數(shù)組件 FunChild</div>
    )
}) // 使用 React.forwardRef 改造函數(shù)組件
class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = React.createRef()
    } 
    componentDidMount(){
        console.log(this.myRef)
        console.log(this.myRef.current)
    }
    render(){
        return (
            <FunChild ref={this.myRef}/>  //直接給函數(shù)組件傳遞 ref
        )
    }
}

感覺 React.forwardRef 就是把 ref 屬性單獨從 props 中抽離出來了。
盡管上述方式實現(xiàn)了在函數(shù)組件上使用 ref 屬性,但此時的 Ref 對象是訪問的函數(shù)組件內(nèi)部的 原生DOM元素 或其他 class組件。也就是說,在這里函數(shù)組件只是起到了一個轉(zhuǎn)發(fā)的作用。

3. 回調(diào) Refs

上述的方式中,我們都是通過創(chuàng)建一個 Ref 對象,通過 ref 屬性的方式掛載到 原生DOM元素 或者 class 組件上用于訪問該元素或?qū)嵗?br /> 實際上,ref 屬性除了可以接收一個 Ref 對象外,還可以接收一個回調(diào)函數(shù)。
當 ref 屬性接收 Ref 對象時,會將其對應的 DOM元素 或者 class組件實例 直接賦值給 Ref 對象中的 current 屬性上。而當 ref 屬性接收一個回調(diào)函數(shù)時,會將其對應的 DOM元素 或 class組件實例作為回調(diào)函數(shù)的參數(shù)調(diào)用回調(diào)函數(shù)。
因此我們可以通過回調(diào) Refs 的方式不依靠 Ref 對象,更靈活地控制要訪問的元素或?qū)嵗?/p>

class App extends React.Component{
    constructor(props){
        super(props)
        this.myRef = null
        this.setMyRef = (element)=>{
            this.myRef = element
        }
    } 
    componentDidMount(){
        console.log(this.myRef)
    }
    render(){
        return (
            <div ref={this.setMyRef}>我是App組件</div>
        )
    }
}

以上就是如何深入理解React的ref 屬性的詳細內(nèi)容,更多關于深入理解React的ref 屬性的資料請關注腳本之家其它相關文章!

相關文章

  • 一文詳解React如何處理表單的復雜驗證邏輯

    一文詳解React如何處理表單的復雜驗證邏輯

    這篇文章主要為大家詳細介紹了React中如何處理表單的復雜驗證邏輯,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-03-03
  • 基于React實現(xiàn)虛擬滾動的方案詳解

    基于React實現(xiàn)虛擬滾動的方案詳解

    這篇文章將以固定高度和非固定高度兩種場景展開React中虛擬滾動的實現(xiàn),文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-03-03
  • 從零開始最小實現(xiàn)react服務器渲染詳解

    從零開始最小實現(xiàn)react服務器渲染詳解

    這篇文章主要介紹了從零開始最小實現(xiàn)react服務器渲染詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 引入代碼檢查工具stylelint實戰(zhàn)問題經(jīng)驗總結(jié)分享

    引入代碼檢查工具stylelint實戰(zhàn)問題經(jīng)驗總結(jié)分享

    eslint的配置引入比較簡單,網(wǎng)上有比較多的教程,而stylelint的教程大多語焉不詳。在這里,我會介紹一下我在引入stylelint所遇到的坑,以及解決方法
    2021-11-11
  • 基于React路由跳轉(zhuǎn)的幾種方式

    基于React路由跳轉(zhuǎn)的幾種方式

    這篇文章主要介紹了React路由跳轉(zhuǎn)的幾種方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • React Grid Layout基礎使用示例教程

    React Grid Layout基礎使用示例教程

    React Grid Layout是一個用于在React應用程序中創(chuàng)建可拖拽和可調(diào)整大小的網(wǎng)格布局的庫,通過使用React Grid Layout,我們可以輕松地創(chuàng)建自適應的網(wǎng)格布局,并實現(xiàn)拖拽和調(diào)整大小的功能,本文介紹了React Grid Layout的基礎使用方法,感興趣的朋友一起看看吧
    2024-02-02
  • React從命令式編程到聲明式編程的原理解析

    React從命令式編程到聲明式編程的原理解析

    這篇文章主要介紹了React從命令式編程到聲明式編程,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • React-hooks中的useEffect使用步驟

    React-hooks中的useEffect使用步驟

    這篇文章主要介紹了React-hooks中的useEffect,對于React組件來說,主作用是根據(jù)數(shù)據(jù)(state/props)渲染UI,除此之外都是副作用(比如手動修改DOM、發(fā)送ajax請求),本文通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2022-05-05
  • React實現(xiàn)表單提交防抖功能的示例代碼

    React實現(xiàn)表單提交防抖功能的示例代碼

    在 React 應用中,防抖(Debounce)技術可以有效地限制函數(shù)在短時間內(nèi)的頻繁調(diào)用,下面我們就來看看如何使用Lodash庫中的debounce函數(shù)實現(xiàn)React表單提交中實現(xiàn)防抖功能吧
    2024-01-01
  • react路由基礎解讀(Router、Link和Route)

    react路由基礎解讀(Router、Link和Route)

    這篇文章主要介紹了react路由基礎解讀(Router、Link和Route),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評論

连云港市| 盈江县| 海淀区| 仙游县| 佛冈县| 新津县| 江口县| 兴山县| 商丘市| 沛县| 包头市| 运城市| 金塔县| 栾城县| 攀枝花市| 本溪| 华池县| 自贡市| 甘南县| 馆陶县| 阿坝县| 大丰市| 靖远县| 山阳县| 正阳县| 农安县| 聂拉木县| 海口市| 稷山县| 玉山县| 古浪县| 方正县| 冕宁县| 枣强县| 上杭县| 叙永县| 孟村| 荆州市| 萨嘎县| 巴林右旗| 廉江市|