欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何深入理解React的ref 屬性

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

概述

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

這個(gè)對(duì)象只有一個(gè)屬性就是 current ,那么這個(gè)對(duì)象是用來干嘛的呢?

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

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

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

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

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

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

1.1 React.createRef()

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

1.2 React.useRef(initialValue)

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

2. ref 屬性的使用

ref 屬性只能被添加到 原生DOM元素 或者 React的 class 組件上。不能在 函數(shù)組件 上使用 ref 屬性,因?yàn)楹瘮?shù)組件沒有實(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 對(duì)象的方式都可以
    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 對(duì)象當(dāng)作普通屬性的方式傳遞給子組件,然后子組件通過 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ā)的原理,我想到的實(shí)現(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}/>
        )
    }
}

這種實(shí)現(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 屬性單獨(dú)從 props 中抽離出來了。
盡管上述方式實(shí)現(xiàn)了在函數(shù)組件上使用 ref 屬性,但此時(shí)的 Ref 對(duì)象是訪問的函數(shù)組件內(nèi)部的 原生DOM元素 或其他 class組件。也就是說,在這里函數(shù)組件只是起到了一個(gè)轉(zhuǎn)發(fā)的作用。

3. 回調(diào) Refs

上述的方式中,我們都是通過創(chuàng)建一個(gè) Ref 對(duì)象,通過 ref 屬性的方式掛載到 原生DOM元素 或者 class 組件上用于訪問該元素或?qū)嵗?br /> 實(shí)際上,ref 屬性除了可以接收一個(gè) Ref 對(duì)象外,還可以接收一個(gè)回調(diào)函數(shù)。
當(dāng) ref 屬性接收 Ref 對(duì)象時(shí),會(huì)將其對(duì)應(yīng)的 DOM元素 或者 class組件實(shí)例 直接賦值給 Ref 對(duì)象中的 current 屬性上。而當(dāng) ref 屬性接收一個(gè)回調(diào)函數(shù)時(shí),會(huì)將其對(duì)應(yīng)的 DOM元素 或 class組件實(shí)例作為回調(diào)函數(shù)的參數(shù)調(diào)用回調(diào)函數(shù)。
因此我們可以通過回調(diào) Refs 的方式不依靠 Ref 對(duì)象,更靈活地控制要訪問的元素或?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 屬性的詳細(xì)內(nèi)容,更多關(guān)于深入理解React的ref 屬性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React中的JSX??{?}的使用詳解

    React中的JSX??{?}的使用詳解

    這篇文章主要介紹了React中的JSX{?}的使用,React使用JSX來替代常規(guī)的JavaScript,JSX可以理解為的JavaScript語(yǔ)法擴(kuò)展,它里面的標(biāo)簽申明要符合XML規(guī)范要求,對(duì)React?JSX使用感興趣的朋友一起看看吧
    2022-08-08
  • react 父組件與子組件之間的值傳遞的方法

    react 父組件與子組件之間的值傳遞的方法

    本篇文章主要介紹了react 父組件與子組件之間的值傳遞的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • 為什么說form元素是React的未來

    為什么說form元素是React的未來

    這篇文章主要介紹了為什么說form元素是React的未來,本文會(huì)帶你聊聊React圍繞form的布局與發(fā)展,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • React中Portals與錯(cuò)誤邊界處理實(shí)現(xiàn)

    React中Portals與錯(cuò)誤邊界處理實(shí)現(xiàn)

    本文主要介紹了React中Portals與錯(cuò)誤邊界處理實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • React Grid Layout基礎(chǔ)使用示例教程

    React Grid Layout基礎(chǔ)使用示例教程

    React Grid Layout是一個(gè)用于在React應(yīng)用程序中創(chuàng)建可拖拽和可調(diào)整大小的網(wǎng)格布局的庫(kù),通過使用React Grid Layout,我們可以輕松地創(chuàng)建自適應(yīng)的網(wǎng)格布局,并實(shí)現(xiàn)拖拽和調(diào)整大小的功能,本文介紹了React Grid Layout的基礎(chǔ)使用方法,感興趣的朋友一起看看吧
    2024-02-02
  • 詳解如何封裝和使用一個(gè)React鑒權(quán)組件

    詳解如何封裝和使用一個(gè)React鑒權(quán)組件

    JavaScript?和?React?提供了靈活的事件處理機(jī)制,特別是通過利用事件的捕獲階段來阻止事件傳播可以實(shí)現(xiàn)精細(xì)的權(quán)限控制,本文將詳細(xì)介紹這一技術(shù)的應(yīng)用,并通過實(shí)踐案例展示如何封裝和使用一個(gè)?React?鑒權(quán)組件,需要的可以參考下
    2024-03-03
  • react如何使用mobx6動(dòng)態(tài)加載數(shù)據(jù)

    react如何使用mobx6動(dòng)態(tài)加載數(shù)據(jù)

    MobX是一個(gè)強(qiáng)大而簡(jiǎn)單的狀態(tài)管理工具,它可以幫助我們更好地組織和管理React應(yīng)用程序中的數(shù)據(jù)流,本文給大家介紹react如何使用mobx6動(dòng)態(tài)加載數(shù)據(jù),感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • 詳解React Native 采用Fetch方式發(fā)送跨域POST請(qǐng)求

    詳解React Native 采用Fetch方式發(fā)送跨域POST請(qǐng)求

    這篇文章主要介紹了詳解React Native 采用Fetch方式發(fā)送跨域POST請(qǐng)求,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • ReactNative實(shí)現(xiàn)的橫向滑動(dòng)條效果

    ReactNative實(shí)現(xiàn)的橫向滑動(dòng)條效果

    本文介紹了ReactNative實(shí)現(xiàn)的橫向滑動(dòng)條效果,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),補(bǔ)充介紹了ReactNative基于寬度變化實(shí)現(xiàn)的動(dòng)畫效果,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • 手把手帶你用React擼一個(gè)日程組件

    手把手帶你用React擼一個(gè)日程組件

    這篇文章主要給大家介紹了關(guān)于利用React擼一個(gè)日程組件的相關(guān)資料,包括日常組件的實(shí)現(xiàn)思路、使用的技術(shù)、以及遇到的技術(shù)難點(diǎn),并給提供了詳細(xì)的實(shí)例代碼,需要的朋友可以參考下
    2021-07-07

最新評(píng)論